Redraw Polyline Leaflet - leaflet

I have a polyline with several points, and I want to redraw it many times inside a loop where I am rearranging the points. I have used setLatLngs function, but it seems to redraw the whole polyline once.
How can I redraw a polyline in a loop?
Here is the code:
test()
{
for (var i=0;i<100;i++)
{
this._polyline.setLatLngs(this.shuffle(this._polylinePoints));
}
}
Here is a jsfiddle.
Thanks!

So, since if you want to see each iteration's configuration for a certain amount of time..you will probably have to use setTimeout, like in the below example.Or make something recursive instead.Here I just constantly make the timeout larger, a recursive approach is a lot more efficient.
self = this;
for (var i=0;i<100;i++) {
setTimeout(function() {
self._polyline.setLatLngs(self.shuffle(self._polylinePoin‌​ts));
},1000*i)
}
Here is recursive example below
self = this;
var runs = 0;
shufflePoints = function() {
if (runs < 100) {
runs++;
self._polyline.setLatLngs(self.shuffle(self._polylinePoin‌​ts));
setTimeout(function() {
shufflePoints()
},1000)
}
}

Related

Leaflet draw delete features with property

Is it possible to delete multiple features from geojson at once by checking property value?
Using for example code below or using Leaflet draw?
function deleteArea() {
var layers = featureGroup.getLayers();
for (var i = 0; i < layers.length; i++) {
if (layers[i].feature.properties.N == 1)
{
"DELETE?" layer[i];
};
}
};
I have big map and some markers have property: feature.properties.N=1. I can delete them using leaflet draw clicking one by one because I changed marker to red for those layers. But it takes some time.. Is it possible to to this at once?
Thank you very much for your time !
Sure you can simply remove the markers from the map / featuregroup with layer.removeFrom(featureGroup)
function deleteArea() {
var layers = featureGroup.getLayers();
for (var i = 0; i < layers.length; i++) {
if (layers[i].feature.properties.N == 1){
layer[i].removeFrom(featureGroup);
};
}
};
PS: I prefer to use Leaflet-Geoman because it is more modern and is still being supported and gets new features

Unity - When does the frameCount goes negative

I'm learning unity scripting. But I don't understand the following :
static private var lastRecalculation = -1;
static function RecalculateValue () {
if (lastRecalculation == Time.frameCount)
return;
ProcessData.AndDoSomeCalculations();
}
I don't get the third line or the condition in the IF statement. I know its a bit amateur, but pls help.
Thank You.
This is from the Time.frameCount documentation. This example shows how to create a function that executes only once per frame, regardless of how many objects you attach your script to. I suspect though that this example is incomplete because it never updates lastRecalculation (or it was assumed you would do so in AndDoSomeCalculations() ).
The reason setting lastRecalculation = -1 initially is so this function runs during the first frame.
Working version:
static var lastRecalculation = -1;
static function RecalculateValue () {
if (lastRecalculation == Time.frameCount) {
return;
}
lastRecalculation = Time.frameCount;
Debug.Log (Time.frameCount);
//ProcessData.AndDoSomeCalculations();
}
function Update () {
RecalculateValue();
}
Attach this script to 2 different GameObjects and run it. You will only see unique frame values 1,2,3,4,5.... even though 2 GameObjects are each calling RecalculateValue()
Now comment out the return and run it again. Now the ProcessData portion of that code runs for both objects every frame and you'll see something like 1,1,2,2,3,3,4,4......

Pure ActionScript 3.0 - Memory Game

I'm a beginner of ActionScript 3.0. I'm making a simple memory game, the tool I'm using is Eclipse with flexsdk plugin. Right now I've done the shuffle and display images, and the cover of the images as well.
My idea is when clicking on the image, the cover will remove and show the image behind of it. After 2 covers are gone, the game will compare and check whether the selected images are match or not, if match both of the images will remain, otherwise the cover will reappear and the game keeps going on. If all of the images are match, a winning line will appear.
The problem I'm facing is I got no idea on how to deal with the images comparison part. I wanted to compare with the index number of array or the name of the images, but I really don't have any idea. I've refer some examples but all of them are develop in CS3 and uses the timeframe which is not exist in pure ActionScript.
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import myclasses.Cover;
public class Prototype extends Sprite {
protected static const WIDTH:int=3;
protected static const HEIGHT:int=2;
protected static const SPACINGX:int=100;
protected static const SPACINGY:int=74;
protected static const OFFSETX:int=96;
protected static const OFFSETY:int=100;
protected static const SIZE:Number=100;
protected static const COLOUR:uint=0x999999;
[Embed(source="images/pic1.jpg")]
protected static const PIC1:Class;
[Embed(source="images/pic2.jpg")]
protected static const PIC2:Class;
[Embed(source="images/pic3.jpg")]
protected static const PIC3:Class;
protected var imagesList:Array=[PIC1,PIC1,PIC2,PIC2,PIC3,PIC3];
protected var X:int;
protected var Y:int=27;
protected var count:int;
//protected var firstTap:Class;
//protected var secondTap:Class;
public function Prototype() {
var shuffled:Array = shuffleList(imagesList.length);
for(var i:int; i<imagesList.length; i++) {
//var colour:uint;
//colour=0x999999;
var j:int = shuffled[i];
var thing:Sprite=new Sprite();
thing.addChild(new imagesList[j]());
thing.x=X;
thing.y=Y;
addChild(thing);
new Cover(this,X,Y,SIZE,COLOUR);
X=X+SPACINGX+OFFSETX;
count++;
if(count == WIDTH){
Y=Y+SPACINGY+OFFSETY;
X=0;
}
addEventListener(MouseEvent.MOUSE_DOWN,selectImages);
}
}
public function selectImages(event:MouseEvent):void {
//(P/S: this is not the actual code)
var target:Sprite = Sprite(event.target)
if(firstTap == null){
firstTap = ; //1st selected image
removeChild(target);
}else if(secondTap == null){
secondTap = ; //2nd selected image
if(firstTap == secondTap){
firstTap = null;
secondTap = null;
}else{
//firstTap = ; //cover back
//secondTap = ; //cover back
secondTap = null;
firstTap = ; //selected another image
}
}
}
protected function shuffleList(n:Number):Array {
var startList:Array = new Array(n);
var endList:Array = new Array(n);
var i:Number, j:Number;
for (i=0; i<n; i++) {
startList[i] = i;
}
for (i=0; i<n; i++) {
j = Math.floor(Math.random()*startList.length);
endList[i] = startList.splice(j,1)[0];
}
return(endList);
}
}
}
Please help me figure out. Thanks.
Well I didn't really go through your code in details, but from looking at it, it seems you are making things really complex. So let me give you a hint in how I would do it...
1) First I would make a 'card' class, which extends sprite or bitmap, mainly containing the image of that card, image of the cover/mask, some animtion methods like hide/show e.t.c, and possibly an 'id' variable to recognize it later, though that is not needed. You can also get away with the array you have, and in that case, skip step 2.
2) Now push two copies of each card in an array.
example [new card('c1'),new card('c1'),new card('c2'),new card('c2'),.....].
3) Now comes the part where you made it most complex, that is, the shuffling of the array. Let's write a custom function for it, shall we?
function shuffleArr(arr):Array
{
var len:int = arr.length();
for(var i:int=0; i<len; i++)
{
//Swap the value at i with a random value within the array;
var tmp_pos:int = Math.floor(Math.random()*len);
while(tmp_pos==i)
{
tmp_pos = Math.floor(Math.random()*len);
}
var tmp_var:card = arr[tmp_pos];
arr[tmp_pos] = arr[i];
arr[i] = tmp_var;
}
}
4) Now that the array is shuffled, you simply have to lay them out in a grid.
for(var row:int=0; row<6; row++)
{
for(var col:int=0; col<6; col++)
{
card_arr[i].x = card_arr[i].width*cols+5;
card_arr[i].y = card_arr[i].height*row+5;
stage.addChild(card[i]);
}
}
5) Now you have to check for user click and take action, and there are many ways to do it, but I will tell one of them...
a) Give the cards a click event handler, this becomes easy if the cards are a class, or you can look into event.target property and use a general click handler. it's up to you.
b) On click, push the card's id in an array. If you did make them into a class, their ids should now be, c1, c2, e.t.c, and you can do
holder_arr.push(this);
this.removeCover();
6) Now you have to make sure, that the holder array can only hold two values at a time. Then do the checking. I am writing a semi-pseudo code with a lot of assumed functions and values:
//Insert
if(holder_arr.length()==2)
{
//flip back the cards and empty the array
holder_arr[0].showCover();
holder_arr[1].showCover();
holder_arr = [];
}
holder_arr.push(this);
...
..
7) For checking make a function and run it every time a card is clicked, and also when a timer ends, to flip back the cards.
function checkCards()
{
if(holder_arr.length==2)
{
if(holder_arr[0].id==holder_arr[1].id)
{
//the cards match
holder_arr[0].vanishAnim();
holder_arr[1].vanishAnim();
holder_arr=[];
}
else
{
holder_arr[0].showCover();
holder_arr[1].showCover();
holder_arr=[];
}
}
}
Obviously you will remove the cards from the actual card_arr too, but when to do that is up to you to figure out ;)
Personally , I find the problem has more to do with the way you shuffle your cards as it makes it a bit more difficult to identify what card is what.
Let's say for instance that instead of shuffling your embed assets , you were first creating your cards , naming them after the image they add , then creating an Array ( or Vector ) of cards and shuffle that Array ( or Vector ), identifying the cards would be fairly easy since you'd only have to compare their name property.
//PSEUDO CODE
- create Array ( Vector ) of embed assets [PIC1, PIC2 , PIC3]
- create cards and use Array ( Vector ) index to identify
each card with the name property
- create a set of six cards
- shuffle set

Google Earth API Moving a polygon

I just starting coding with Google Earth using the GEPlugin control for .Net and still got a lot to learn.
What has got me puzzled is when I try to drag a polygon.
The method below is called whenever the mousemove event fires and should be moving each point of the polygon while retaining the orginal shape of the polygon. The lat / long for each point is changed but the polygon does not move position on the map.
Will moving a point in a polygon cause it to redraw, do I need to call a method to force a redraw or perhaps do something else entirely?
Thanks!
private void DoMouseMove(IKmlMouseEvent mouseEvent)
{
if (isDragging)
{
mouseEvent.preventDefault();
var placemark = mouseEvent.getTarget() as IKmlPlacemark;
if (placemark == null)
{
return;
}
IKmlPolygon polygon = placemark.getGeometry() as IKmlPolygon;
if (polygon != null)
{
float latOffset = startLatLong.Latitude - mouseEvent.getLatitude();
float longOffset = startLatLong.Longitude - mouseEvent.getLongitude();
KmlLinearRingCoClass outer = polygon.getOuterBoundary();
KmlCoordArrayCoClass coordsArray = outer.getCoordinates();
for(int i = 0; i < coordsArray.getLength(); i++)
{
KmlCoordCoClass currentPoint = coordsArray.get(i);
currentPoint.setLatLngAlt(currentPoint.getLatitude() + latOffset,
currentPoint.getLongitude() + longOffset, 0);
}
}
}
}
Consider voting for these issues to be resolved
http://code.google.com/p/earth-api-utility-library/issues/detail?id=33
http://code.google.com/p/earth-api-samples/issues/detail?id=167
You may find some hints at the following link:
http://earth-api-utility-library.googlecode.com/svn/trunk/extensions/examples/ruler.html
UPDATE:
I've released the extension library: https://bitbucket.org/mutopia/earth
See https://bitbucket.org/mutopia/earth/src/master/sample/index.html to run it.
See the drag() method in the sample code class, which calls setDragMode() and addDragEvent() to enable dragging of the KmlPolygon.
I successfully implemented this using takeOverCamera in the earth-api-utility-library and three events:
setDragMode: function (mode) {
// summary:
// Sets dragging mode on and off
if (mode == this.dragMode) {
Log.info('Drag mode is already', mode);
} else {
this.dragMode = mode;
Log.info('Drag mode set', mode);
if (mode) {
this.addEvent(this.ge.getGlobe(), 'mousemove', this.dragMouseMoveCallback);
this.addEvent(this.ge.getGlobe(), 'mouseup', this.dragMouseUpCallback);
this.addEvent(this.ge.getView(), 'viewchange', this.dragViewChange, false);
} else {
this.removeEvent(this.ge.getGlobe(), 'mousemove', this.dragMouseMoveCallback);
this.removeEvent(this.ge.getGlobe(), 'mouseup', this.dragMouseUpCallback);
this.removeEvent(this.ge.getView(), 'viewchange', this.dragViewChange, false);
}
}
},
This is in a utility library within a much larger project. dragMode is a boolean which adds and removes events. These three events control what happens when you drag. addEvent and removeEvent are my own wrapper functions:
addEvent: function (targetObject, eventID, listenerCallback, capture) {
// summary:
// Convenience method for google.earth.addEventListener
capture = setDefault(capture, true);
google.earth.addEventListener(targetObject, eventID, listenerCallback, capture);
},
removeEvent: function (targetObject, eventID, listenerCallback, capture) {
// summary:
// Convenience method for google.earth.removeEventListener
capture = setDefault(capture, true);
google.earth.removeEventListener(targetObject, eventID, listenerCallback, capture);
},
Ignoring the minor details, all the important stuff is in the callbacks to those events. The mousedown event locks the camera and sets the polygon I'm dragging as the dragObject (it's just a variable I'm using). It saves the original lat long coordinates.
this.dragMouseDownCallback = lang.hitch(this, function (event) {
var obj = event.getTarget();
this.lockCamera(true);
this.setSelected(obj);
this.dragObject = obj;
this.dragLatOrigin = this.dragLatLast = event.getLatitude();
this.dragLngOrigin = this.dragLngLast = event.getLongitude();
}
The mousemove callback updates to the latest lat long coordinates:
this.dragMouseMoveCallback = lang.hitch(this, function (event) {
if (this.dragObject) {
var lat = event.getLatitude();
var lng = event.getLongitude();
var latDiff = lat - this.dragLatLast;
var lngDiff = lng - this.dragLngLast;
if (Math.abs(latDiff) > this.dragSensitivity || Math.abs(lngDiff > this.dragSensitivity)) {
this.addPolyCoords(this.dragObject, [latDiff, lngDiff]);
this.dragLatLast = lat;
this.dragLngLast = lng;
}
}
});
Here I'm using some fancy sensitivity values to prevent updating this too often. Finally, addPolyCoords is also my own function which adds lat long values to the existing coordinates of the polygon - effectively moving it across the globe. I do this with the built in setLatitude() and setLongitude() functions for each coordinate. You can get the coordinates like so, where polygon is a KmlPolyon object:
polygon.getGeometry().getOuterBoundary().getCoordinates()
And of course, the mousedown callback turns off the drag mode so that moving the mouse doesn't continue to drag the polygon:
this.dragMouseUpCallback = lang.hitch(this, function (event) {
if (this.dragObject) {
Log.info('Stop drag', this.dragObject.getType());
setTimeout(lang.hitch(this, function () {
this.lockCamera(false);
this.setSelected(null);
}), 100);
this._dragEvent(event);
this.dragObject = this.dragLatOrigin = this.dragLngOrigin = this.dragLatLast = this.dragLngLast = null;
}
});
And finally, _dragEvent is called to ensure that the final coordinates are the actual coordinates the mouse event finished with (and not the latest mousemove call):
_dragEvent: function (event) {
// summary:
// Helper function for moving drag object
var latDiff = event.getLatitude() - this.dragLatLast;
var lngDiff = event.getLongitude() - this.dragLngLast;
if (!(latDiff == 0 && lngDiff == 0)) {
this.addPolyCoords(this.dragObject, [latDiff, lngDiff]);
Log.info('Moved ' + latDiff + ', ' + lngDiff);
}
},
The mousemove callback isn't too important and can actually be ignored - the only reason I use it is to show the polygon moving as the user moves their mouse. Removing it will result in the object being moved when they lift their mouse up.
Hopefully this incredibly long answer gives you some insights into how to implement dragging in the Google Earth API. And I also plan to release my library in the future when I've ironed out the kinks :)

Touches on transparent PNGs

I have a PNG in a UIImageView with alpha around the edges (let's say a circle). When I tap it, I want it to register as a tap for the circle if I'm touching the opaque bit, but a tap for the view behind if I touch the transparent bit.
(BTW: On another forum, someone said PNGs automatically do this, and a transparent PNG should pass the click on to the view below, but I've tested it and it doesn't, at least not in my case.)
Is there a flag I just haven't flipped, or do I need to create some kind of formula: "if tapped { get location; calculate distance from centre; if < r { touched circle } else { pass it on } }"?
-k.
I don't believe that PNGs automatically do this, but can't find any references that definitively say one way or the other.
Your radius calculation is probably simpler, but you could also manually check the alpha value of the touched pixel in your image to determine whether to count it as a hit. This code is targetted at OS X 10.5+, but with some minor modifications it should run on iPhone: Getting the pixel data from a CGImage object. Here is some related discussion on retrieving data from a UIImage: Getting data from an UIImage.
I figured it out...the PNG, bounding box transparency issue and being able to click through to another image behind:
var hitTestPoint1:Boolean = false;
var myHitTest1:Boolean = false;
var objects:Array;
clip.addEventListener(MouseEvent.MOUSE_DOWN, doHitTest);
clip.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
clip.buttonMode = true;
clip.mouseEnabled = true;
clip.mouseChildren = true;
clip2.addEventListener(MouseEvent.MOUSE_DOWN, doHitTest);
clip2.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
clip2.buttonMode = true;
clip2.mouseEnabled = true;
clip2.mouseChildren = true;
clip.rotation = 60;
function doHitTest(event:MouseEvent):void
{
objects = stage.getObjectsUnderPoint(new Point(event.stageX, event.stageY));
trace("Which one: " + event.target.name);
trace("What's under point: " + objects);
for(var i:int=0; i
function stopDragging(event:MouseEvent):void
{
event.target.stopDrag();
}
function realHitTest(object:DisplayObject, point:Point):Boolean
{
/* If we're already dealing with a BitmapData object then we just use the hitTest
* method of that BitmapData.
*/
if(object is BitmapData)
{
return (object as BitmapData).hitTest(new Point(0,0), 0, object.globalToLocal(point));
}
else {
/* First we check if the hitTestPoint method returns false. If it does, that
* means that we definitely do not have a hit, so we return false. But if this
* returns true, we still don't know 100% that we have a hit because it might
* be a transparent part of the image.
*/
if(!object.hitTestPoint(point.x, point.y, true))
{
return false;
}
else {
/* So now we make a new BitmapData object and draw the pixels of our object
* in there. Then we use the hitTest method of that BitmapData object to
* really find out of we have a hit or not.
*/
var bmapData:BitmapData = new BitmapData(object.width, object.height, true, 0x00000000);
bmapData.draw(object, new Matrix());
var returnVal:Boolean = bmapData.hitTest(new Point(0,0), 0, object.globalToLocal(point));
bmapData.dispose();
return returnVal;
}
}
}