OpenLayers Vector Layer Maximum number of features - vector

I was wondering if it is possible to limit the number of features you an draw on a vectorylayer. If I already have a polygon drawn, and go to draw another it will delete the first feature.
If not is it possible to add a listener to the vector layer, so that I can erase all features when clicking to draw?
Thanks!!!

You can't set max number of features on Vector Layer, but it has a whole lot of events where you can inject your own logic. Here are available events:
"beforefeatureadded", "beforefeaturesadded",
"featureadded", "featuresadded", "beforefeatureremoved",
"beforefeaturesremoved", "featureremoved", "featuresremoved",
"beforefeatureselected", "featureselected", "featureunselected",
"beforefeaturemodified", "featuremodified", "afterfeaturemodified",
"vertexmodified", "vertexremoved", "sketchstarted",
"sketchmodified", "sketchcomplete", "refresh"
You can use "beforefeatureadded" for instance:
your_vectror_layer.events.on({'beforefeatureadded': function(){
//Remove first feature or whatever you want to do
}});

you can make a button and when you click on it, it will remove all the features in your vector layer :
map.layers[1].removeAllFeatures();
Here 1 is the id of my layer (my vector layer is the second one after an OSM layer)
Good Luck !

Related

Routing with avoid area and geofence / polygon

I want to avoid specific streets when using the routing API. I have data points to create a geofence or polygon to represent those specific streets.
The router API accepts only up to 20 bounding boxes. I tried to send 20 avoid area bounding boxes to represent the road, but the result is not reliable (e.g. on diagonal roads).
Is there a way to send a geofence/polygon instead of bounding boxes?
Or any other way to avoid certain streets?
Thank you very much
Please try to use avoid[segments] instead of avoid[areas] for avoiding specific roads. In the case of having too many roads to avoid, you can also put the avoid[segments] parameters into request body and send a POST request to the same endpoint.
In order to get the segmentId of the roads you would like to avoid, you can do a normal routing call with parameter spans=segmentId added and then look at the topologySegmentId attributes in spans section of the response.
https://developer.here.com/documentation/routing-api/api-reference-swagger.html
HERE Routing API now supports polygons for avoid area, https://www.here.com/learn/blog/routing-supports-polygons-for-avoid-areas
You have to make below calls for your usecase.
1>Rest call to get segmentId For the route.
https://router.hereapi.com/v8/routes? apikey={your_app_id}& origin=32.834496,74.81515& destination=32.811632,75.816037& return=polyline,summary,actions,instructions& spans=segmentId& transportMode=car&
2>Rest Call to get the get Route with avoid[segments]
https://router.hereapi.com/v8/routes? apikey={your_app_id}& origin=32.834496,74.81515& destination=32.811632,74.816037& return=polyline,summary,actions,instructions& spans=segmentId& transportMode=car& avoid[segments]=here:cm:segment:808368834,here:cm:segment:808095972

Places autocomplete widget : bounds bias seems too weak

I want the Places autocomplete Widget to suggest places within France, but not restricted to France. I followed the official guide and added bounds (I set a rectangle bound that does not overflow outside of France), but the places returned for the first digits chars are most of the time out of the bounds.
I saw in the reference that the bound is biased and not restricted to the bound, but the bias seems too weak. Is there any way to make it stronger? (a parameter ?)
Example : https://codepen.io/benjamin-chevillon/pen/XBrNLZ :
new google.maps.places.Autocomplete(inputBounded, {
types: ["geocode"],
bounds: autocompleteBounds
});
When I type "33" for example, 4 of the 5 suggestions are out of the bounds. Whereas the widget restricted to France returns a lot of places with '33'.
On the official Google example, the autocomplete bounds is linked to the map. By default, the map is centered on Sydney. If you type "33" you'll get Australia's places. But if you move to France you will get European suggestions (but outside of France). I saw that it happens only when we start typing number. But it is a common way in France to describe a postal address.
I created an issue https://issuetracker.google.com/issues/111234226, but they redirected me on SO.
In order to restrict results of autocomplete widget to your bounds you have to use strictBounds parameter that was mentioned in issue tracker:
https://developers.google.com/maps/documentation/javascript/reference/3/places-widget#AutocompleteOptions.strictBounds
strictBounds - A boolean value, indicating that the Autocomplete widget should only return those places that are inside the bounds of the Autocomplete widget at the time the query is sent. Setting strictBounds to false (which is the default) will make the results biased towards, but not restricted to, places contained within the bounds.
So, your code should be rewritten as
new google.maps.places.Autocomplete(inputBounded, {
types: ["geocode"],
bounds: autocompleteBounds,
strictBounds: true
});
I hope this helps!

Google map how to display a dragable marker based on coordinates and return new coordinates

I have to write a script for Google Maps V3 which will do the following:
Place a marker on a map based on a set of coordinates and possbibly change the address after the page has been loaded
Allow the user the drag the mark to replace it elsewhere
Collect the new coordinates once the marker has been moved.
The first part is basic enough and should be fine, changing the address after the page is loaded should only be a matter of calling back the same function?
I am not sure where to start on the draggable marker and collecting hew coordinates.
Would anyone know of scripts / API's or where in the doc should I start?
Have you checked the Google Maps Javascript API V3 Reference to see whether the google.maps.Marker class has :
a draggable option
an dragend event
a getPosition method
Hint: The answer might just be "yes" to all three, and you don't need much else to solve your problem.

After Effects Expressions - controling comps from main comp using an "Expressions Layer"

THE GOAL I WANT TO ACHEIVE:
Control AE timelines using ONE EXPRESSION LAYER (much like using Actionscript) to trigger frequently used comps such as blinking, walking, flying etc... for cartoon animation.
I want animate a the blinking of a cartoon character. (and other actions, explained below) Rather than "re posting" the comp or key frames movements every time I want a blink or a particular action, I want to create a script where I can trigger the Blink comp to play. Is this possible? (Sidenote: A random blink through entire movie would be nice) but I still want to know how to do this for the reasons below.
Ideally: I would like to create an "Expressions layer" in the main comp to TRIGGER other comps to play. At certain points I would like to add triggers to call frequently used comps that contain actions like.. Blinking, Walking, Flying, Look Left and Right etc...
IT WOULD BE AMAZING IF somehow we could trigger other comps to begin, repeat, stop, maybe reverse, and do this all from one Main Comp using an expression layer.
WHY DO IT THIS WAY?
Why not just paste a comp in the spot you want it to play every time you want such action? Well in after effects if you wanted a "blink comp" to play 40 times in two minutes you would have to create 40 layers, or pate the key frames on that comp 40 times. Wouldn't it be awesome to trigger or call it from one one layer when you wanted it from one expressions layer?
We do something like this in Flash using Actionscript all the time. It would be awesome if there was a method out there to achieve this effect. This would be an OUTSTANDING tutorial and I believe it would be very popular if someone did it. It could be used for a MULTITUDE of amazing effects and could save a ton of time for everyone. Heck, help me figure this out and perhaps I will make a tutorial.
Thank you all ye "overflowing Stackers" who contribute! :)
I found the answer and that is...
IT'S NOT POSSIBLE.
After Effects expressions can not control other timelines. Unfortunately you have to put an expression on each layer you want to affect.
The next best solution, and to achieve something close to what I was asking can be found on this link: motionscript.com/design-guide/marker-sync.html
We can only hope that Adobe will someday give the power to expressions like they did with action-script.
HOPEFULLY SOON! Anyone reading this who works for Adobe please plead our case. Thanks
Part 1: Reference other layers in pre-Comps
Simply replace "thisComp" with "comp("ComName")"
To reference Effect-Controllers between compositions, follow the below formula:
comp("ComName").layer("LayerWithExpression").effect("EffectControlerName")("EffectControllerType")
More In-depth Answer: Adobe's Docs - Skip to the Layer Sub-objects part
As I understand the Adobe documentation, only Layers can be accessed,
not footage. What this means is that you will need to create your
expression link utilizing a pre-Comp. Footage can not access this so
that also means no nulls, adjustment layers, etc.
As an added bonus, if you use the essential graphics panel, you can put all the controllers in one pre-comp, but have the controls available no matter which comp you are in. Just select it in the Essential-Graphics dropdown.
Part 2: Start/End based on other layers within pre-comps:
Regarding the next part where you want the expressions to activate based on other compositions, I recommend using the in-out Point expression.
inPoint | Return type: Number. Returns the In point of the layer, in seconds.
outPoint | Return type: Number. Returns the Out point of the layer, in seconds.
If you utilize the start time overrides you can pull this from:
startTime | Return type: Number. Returns the start time of the layer, in seconds.
Alternate Option:
I would recommend avoiding this as the keyframes are basically referenced as an index, so things can get messed up if you add one ahead of a keyframe you were already using - def incorporate some error handling.
Refer to the Key attributes and methods (expression reference) Here
Part 3: Interpolation & Time Reversal
You can time reverse the layer in the rightclick->time, otherwise this is all interpolation expressions like loop out etc - you can loopOut("FOO") a pre-comp if you not only cut it correctly, but also enable time remapping.
then use this to loop those keyframes;
try{ timeStart = thisProperty.key(1).time; duration = thisProperty.key(thisProperty.numKeys).time-timeStart; pingPong =
false; //change to true value if you want to loop animationn back &
forth quant=Math.floor((time-timeStart)/duration);
if(quant<0) quant = 0
if(quant%2 == 1 && pingPong == true){
t = 2*timeStart+ (quant+1)*duration - time;
}
else{
t = time-quant*duration;
}
}
catch(err){
t = time;
}
thisProperty.valueAtTime(t)

google maps api v3 exporting kml file of current map

I have a google map component in my application that allows the user to draw polygons, lines, and marker. Now I want to implement a button that allows the user to export a kml file of the stuff that he/she draw in the map.
Any suggestion for the best approach to do so.
Your comments and contribution is highly appreciated
I'll summarize my idea as storing coordinates as the user draws, then when the "Output KML" button is clicked, format the saved coordinate data and place it in a textarea to be copied (unless there's a way to prompt as a download?).
Here's how I save data when the user completes a drawing element:
http://jsfiddle.net/8bwG2/
(I don't know a good way of detecting edits.)
First, add event listeners for each drawing type (line, polygon, marker), to fire when it is complete. You need a separate event listener for each type. Here's one for Polylines, and each listener will return the type of drawing element that was just completed.
google.maps.event.addDomListener(drawingManager, 'polylinecomplete', function(line) {
path = line.getPath();
document.getElementById("action").value += "#polyline\n";
for(var i = 0; i < path.length; i++) {
document.getElementById("action").value += path.getAt(i) + "\n";
}
});
I am placing the coordinates straight into a shared textarea but they should instead go into an array of arrays variable, with one variable for polygons, one for polylines and one for markers.
When reading from these internal variables, convert the Google Maps LatLngs to KML format long,lat,altitude. You will have to get creative with each element's name and description.
Finally, when the KML is requested, loop through the markers, line, and polygon variable to generate KML formatted elements, such as Point-coordinates, LineString, and Polygon-outerBoundaryIs

Resources