LeafletJS markers move on zoom - dictionary

Using LeafletJS which is ace, well until now :P We don't have a JSON object or anything, so I am taking the values out of the HTML (title, latlng) and creating markers. Generally that works ok, however there is an issue with the plotting of them. When the map is really zoomed in they seem to be ok, but when you zoom out (like the map is initially), they are way off. They then move on zoom.
So, what am I doing wrong?
http://jsbin.com/edegox/1
http://jsbin.com/edegox/1/edit
Cheers
Tom

The solution to this is quite simple. Leads should have posted it.
when your markers are moving around your map it's because the map doesn't know the size of your marker and/or it doesn't know the point of your marker that marks the location.
your marker icon code might look like this:
var locationIcon = L.icon({iconUrl:'location_marker_icon.png'});
now, let's suppose your image is 24px wide and 36px tall. To keep your marker from moving around, you simply specify the size of the marker, and the "anchor point"...
var locationIcon = L.icon({
iconUrl:'location_marker_icon.png',
iconSize: [24,36],
iconAnchor: [12,36]
});
This will make the center pixel on the bottom represent the exact lat/lng point you specified the marker for, and it will keep it anchored there!

Given an icon that looks like this, with an overall size of 98px wide by 114px tall:
iconSize will be [98, 114]. This is the overall size of the icon.
Your iconAnchor will be [49, 114]. The icon anchors first numeral can be calculated by taking the first numeral in the iconSize and dividing by 2 (i.e., 98 ÷ 2 = 49)
If you wanted to use this icon example, your final code should look like this:
var locationIcon = L.icon({
iconUrl:'location_marker_icon.png',
iconSize: [98, 114],
iconAnchor: [49, 114]
});
Here's a Gist example you can test with (I highlighted the lines in question) https://gist.github.com/anonymous/fe19008c911e1e6b6490#file-index-html-L38-L44

Related

Add Shape created by .intersect to a Canvas?

I am trying to highlight an Area that gets intersected by 2 Circle:
Example 1.:
The Yellow dots get, for testing purposes, random values. Those are used to draw a circle around, as well as to store an ellipse in the Background. In the Case of no intersection, the GUI acts correctly and display this:
After the random Values, the Shapes intersect. As I cannot seem to be able to add the new Shape made trough .intersect(), I just did a quick sp.setContent(), and got this image:
This basicly shows me the intersected space and colors it blue.
Everything is drawn on a Canvas, which basicly does the following:
Canvas canvas = new Canvas(250, 250);
....
gc = canvas.getGraphicsContext2D();
canvas.setHeight(imgTemp.getHeight());
canvas.setWidth(imgTemp.getWidth());
gc.drawImage(imgTemp, 0, 0);
Aswell as with some other Loops to draw the shapes and the circles.
Now, the code for the intersect is the following:
if (!(e.equals(eT))) {
if (e.getBoundsInParent().intersects(eT.getBoundsInParent())) {
System.out.println("Collision detected!");
Shape inter = Shape.intersect(e, eT);
if(inter.getBoundsInLocal().getWidth() > 0 && 0 < inter.getBoundsInLocal().getHeight()){
inter.setFill(BLUE);
inter.setStrokeWidth(3);
sp.setContent(inter);
}
}
I'm not that used to JavaFX and have only begun really working on it this Weekend for a small Project, but I am guessing that I might need to change from canvas to something else to make use of the shapes? Or is there a way to "tranform" the Shape of the intersect into something drawable by GraphicsContext2D?
Why don't you just put your Canvas into a Group and then add your shapes to the same Group. Why would you insist on drawing everything into the Canvas? A Canvas is just a Node like all the other Shapes and you can mix them freely in the SceneGraph.
Another question would be why you are using the Canvas at all if you have already realized that this leads to problems in your case.

Coloring the area under graph

I am stuck and thought to get your help to move on forward.
I am trying to shade the area under my line chart with different colors. I know there is the concept of gradient but I want to color it based on my data.
For example and value below zero is red , between 1 and 5 is pink and above 5 is black. Is there a way to this ?
this is the snippet for my shaded area
var area = d3.svg.area()
.x(function (d) { return x(d.timex); })
.y0(height)
.y1(function (d) { return y(d.conct); });
svg.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area);
I would try using a clip path, one for each different color you want to show with your area. In theory, the clip path will be multiple rectangle indicating where you want the area object to show through. You'll need one clip path and area for each color.
In practice, I found Mike Bostock use a clip path (briefly) with D3 here, and MDN has a reasonably good reference here. You can go from there to google around for more examples; just make sure they're talking about SVG clip paths.

How does masking work in C4?

I've set up a shape and an image that I'd like to mask my shape with. I set both their centers to the center of the canvas and then I wrote:
shape.mask = img;
But this gives me very strange results. The shape appears to be masked... sort of... the only part that shows up is the bottom right corner, the left half and the top half are cut off.
I also tried with two images, and with two shapes. Neither seems to work.
Am I missing a step? Perhaps the image I'm trying to mask with doesn't have any alpha values (I'm guessing here, I saw it mentioned in another question that they have to be images with alpha values and they mentioned .png files, so that's what I used)?
When I tried with two shapes, I tried setting the alpha value of the fill of the shape I wanted to mask with to 0.5 and 0.0 and also just setting the fillColor to Nil... still nothing.
I also (in a desperate last attempt) tried the method described here: Mask a view in Objective-C but I'm not very good with objective-c on its own so that didn't work either.
What is the correct way to mask in C4?
You're masking the right way.
What's going on is that an object's mask must be positioned based on the coordinate space of the object itself. When you add a subview to an object, it gets positioned relative to the object's {0,0}.
The following code will work and show you 2 things.
First, the masking shape is positioned to the center of the object, and NOT the center of the canvas:
s.center = CGPointMake(m.width/2,m.height/2);
Second, when you touch the canvas the animation will trigger the mask to move to the "center" coordinate of the canvas, but you'll notice that it goes further off. This is because it counts its position from the origin of the image.
#implementation C4WorkSpace {
C4Image *m;
C4Shape *s;
}
-(void)setup {
m = [C4Image imageNamed:#"C4Sky"];
s = [C4Shape ellipse:CGRectMake(0, 0, m.height, m.height)];
m.center = self.canvas.center;
s.center = CGPointMake(m.width/2,m.height/2);
m.mask = s;
[self.canvas addImage:m];
}
-(void)touchesBegan {
s.animationDuration = 1.0f;
s.center = self.canvas.center;
}
#end

Check if a point is in the viewport

I check like this:
enter code here
var point = new g.LatLng(parseFloat(lat),parseFloat(lng));
var bounds = map.getBounds();
if (bounds.contains(point))
{
the point is in the viewport
}
But when I change the zoom level, thefore the coordinates of the viewport, the "invisible" point is NOT detected as "visible", I mean in the viewport.
Point is not a marker !
I wrote a hack that might work in your scenario. As far as I tested, it works when there's not a lot of the world repeated. I know this hack is unreliable if the world is displayed twice or more. So if you can set the map's minZoom, you would prevent such cases.
The idea is to divide the map in a left and right half, and check whether the marker is in either half.
Here's the hack, use carefully
http://jsfiddle.net/QeR2D/3/
If you have more than the whole circumference of the Earth in your viewport, things can go wrong.
The left-hand edge may be further east than the right-hand edge. map.getBounds() gets the wrong result in this case.
The left-hand edge may be west of the right-hand edge, but area defined by the longitudes of both may not include the point of interest.
Here's an image of a map I developed for another answer which demonstrates that. The left-hand edge is at 83°E and the right-hand edge at 162°E. The markers are at 54°W and 8°W and neither are within map.getBounds() — they don't lie between 83°E and 162°E — even though they are obviously on the map.
I'm not aware of any method in the API which allows this to be catered for.

3D, AS3, Flex - Convert degrees of rotation to visible height

I need to know what the visible height of a display object will be after I change it's rotationX value.
I have an application that allows users to lay out a floor in 3D space. I want the size of the floor to automatically stretch after a 3D rotation so that it always covers a certain area.
Anyone know a formula for working this out?
EDIT: I guess what I am really trying to do is convert degrees to pixels.
On a 2D plane say 100 x 100 pixels, a -10 degree change on rotationX means that the plane has a gap at the top where it is no longer visible. I want to know how many pixels this gap will be so that I can stretch the plane.
In Flex, the value for the display objects height property remains the same both before and after applying the rotation, which may in fact be a bug.
EDIT 2: There must be a general math formula to work this out rather than something Flash/Flex specific. When viewing an object in 3D space, if the object rotates backwards (top of object somersaults away from the viewer), what would the new visible height be based on degrees of rotation? This could be in pixels, metres, cubits or whatever.
I don't have a test case, but off the top of my head I'd guess something like:
var d:DisplayObject;
var rotationRadians:Number = d.rotationX * Math.PI / 180;
var visibleHeight:Number = d.height * Math.cos(rotationRadians);
This doesn't take any other transformations into account, though.
Have you tried using the object's bounding rectangle and testing that?
var dO:DisplayObject = new DisplayObject();
dO.rotation = 10;
var rect:Rectangle = dO.getRect();
// rect.topLeft.y is now the new top point.
// rect.width is the new width.
// rect.height is the new height.
As to the floor, I would need more information, but have you tried setting floor.percentWidth = 100? That might work.
Have you checked DisplayObject.transform.pixelBounds? I haven't tried it, but it might be more likely to take the rotation into account.
Rotation actually changes DisplayObject's axis's (i.e. x and y axes are rotated). That is why you are not seeing the difference in height. So for getting the visual height and y you might try this.var dO:DisplayObject = new DisplayObject();
addChild();
var rect1:Rectangle = dO.getRect(dO.parent);
dO.rotation = 10;
var rect2:Rectangle = dO.getRect(dO.parent);
rect1 and rect2 should be different in this case. If you want to check the visual coordinates of the dO then just change dO.parent with root.

Resources