Thanks for your help Juguang. I changed the things you suggested.
Now it is working mostly, but there is a little problem with
the globalToLocal method that I am using. It looks like it places the
shape a little bit higher than where it is supposed to be and moves it
a little bit higher when I zoom out and lower when I zoom in. The
behavior is the same regardless of whether I use the matrix to
transform or not. Am I misunderstanding something about how
globalToLocal works or is there another way?
public class RectangleGeoZone extends OverlayBase
{
private var map:IMap;
private var location:LatLng;
private var latConv:Number;
private var lngConv:Number;
private var latlngs:Array = new Array(4);
private var matrix:Matrix = new Matrix();
private var rectangle:Shape;
public function RectangleGeoZone(location:LatLng, width:Number,
height:Number)
{
super();
this.location = location;
this.width = width;
this.height = height;
//convert lat/lng to meters
latConv = location.distanceFrom(new LatLng(location.lat() + 0.1,
location.lng())) * 10;
lngConv = location.distanceFrom(new LatLng(location.lat(),
location.lng() + 0.1)) * 10;
latlngs[0] = location;
latlngs[1] = new LatLng(location.lat(), location.lng() + (width
/
lngConv));
latlngs[2] = new LatLng(location.lat() - (height / latConv),
location.lng() + (width / lngConv));
latlngs[3] = new LatLng(location.lat() - (height / latConv),
location.lng());
rectangle = new Shape();
this.addEventListener(MapEvent.OVERLAY_ADDED, onOverlayAdded);
this.addEventListener(MapEvent.OVERLAY_REMOVED,
onOverlayRemoved);
}
public override function getDefaultPane(map:IMap):IPane
{
this.map = map;
return map.getPaneManager().getPaneById(PaneId.PANE_OVERLAYS);
}
public function getLatLngs():Array {
return latlngs;
}
public function getPoints():Array {
var points:Array = new Array(latlngs.length);
for (var i:int=0; i<latlngs.length; i++) {
points[i] =
rectangle.globalToLocal(latlngToPoint(LatLng(latlngs
[i])));
}
return points;
}
public function onOverlayAdded(event:MapEvent):void {
addChild(rectangle);
positionOverlay(true);
}
public function onOverlayRemoved(event:MapEvent):void {
removeChild(rectangle);
rectangle.graphics.clear();
}
public override function positionOverlay(zoomChanged:Boolean):void
{
//redraw if zoom changes
if (zoomChanged) {
draw();
}
//reposition
var myPoint:Point = latlngToPoint(location);
rectangle.x = myPoint.x;
rectangle.y = myPoint.y;
}
private function draw():void {
rectangle.graphics.clear();
rectangle.graphics.beginFill(Color.BLUE, .5);
var points:Array = getPoints();
var point:Point = Point(points[0]);
rectangle.graphics.moveTo(point.x, point.y);
for (var i:int=0; i<points.length; i++) {
point = Point(points[(i + 1) % points.length])
rectangle.graphics.lineTo(point.x, point.y);
}
rectangle.graphics.endFill();
matrix.rotate(45 * (Math.PI / 180));
rectangle.transform.matrix = matrix;
}
private function latlngToPoint(latlng:LatLng):Point {
return pane.fromLatLngToPaneCoords(latlng);
}
private function pointToLatLng(point:Point):LatLng {
return pane.fromPaneCoordsToLatLng(point);
}
}
On Jul 16, 7:05 pm, Juguang XIAO <[email protected]> wrote:
> Hi,
>
> I have looked at your code, and can only offer you two points this time;
> when i got less busy, i may give you more detailed answers.
>
> 1. For rotation, there is a common misunderstanding on how matrix works. The
> center/origin point your overlay is rotating around, is not as what you
> thought. You need to read through this article to get
> it.http://www.senocular.com/flash/tutorials/transformmatrix/
>
> 2. For making overlay, some coding practise in your code, i beleive, can be
> improved for style and performance. In short,
>
> 2.1 Map should not be passed into overlay in its constructor.
>
> 2.2 I was a bit confused in what unit of width/height in constructor you
> use.
>
> 2.3 addChild(rectangle); should be moved from positionOverlay(), to
> constructor or overlay_added event listener. this is a serious performance
> issue.
>
> 2.4 your shape needs to be drawn once for all, rather than redrawn each time
> when it rotate in positionOverlay each time. If you really want to roate it,
> you should rotate the shape itself, not recalculate 4 corners and redraw.
>
> This is my article addressing this custom overlay issue. It is one month
> old, and I will update it with my recent thought
> later.http://postbabel.com/wordpress/2009/06/extending-google-maps-api-for-...
>
> Sorry, I can only give you these this briefly. When I got time, I will get
> back to you at code level.
>
> Juguang
>
>
>
> On Fri, Jul 17, 2009 at 1:43 AM, Jeffrey <[email protected]> wrote:
>
> > I am trying to place a rectangle on a map that can be moved, resized
> > and rotated. To do the rotation, I wanted to use flex's built-in
> > Matrix class. When i do the transform on the points, the shape ends
> > up moving around the map instead of staying in the same place when I
> > drag the map. Here is some simplified code.
>
> > Am I misunderstanding how to do matrix transformations or is the
> > problem with lat/lng ration being different than x/y ratio?
>
> > public class RectangleGeoZone extends OverlayBase
> > {
> > private var map:Map;
> > private var location:LatLng;
> > private var latConv:Number;
> > private var lngConv:Number;
> > private var latlngs:Array = new Array(4);
>
> > private var matrix:Matrix = new Matrix();
>
> > private var rectangle:Shape;
>
> > public function RectangleGeoZone(map:Map, location:LatLng,
> > width:Number, height:Number)
> > {
> > super();
> > this.map = map;
> > this.location = location;
> > this.width = width;
> > this.height = height;
>
> > latConv = location.distanceFrom(new LatLng(location.lat() +
> > 0.1,
> > location.lng())) * 10;
> > lngConv = location.distanceFrom(new LatLng(location.lat(),
> > location.lng() + 0.1)) * 10;
>
> > latlngs[0] = location;
> > latlngs[1] = new LatLng(location.lat(), location.lng() +
> > (width /
> > lngConv));
> > latlngs[2] = new LatLng(location.lat() - (height / latConv),
> > location.lng() + (width / lngConv));
> > latlngs[3] = new LatLng(location.lat() - (height / latConv),
> > location.lng());
>
> > matrix.rotate(45 * (Math.PI / 180));
> > //matrix.scale(2, 2);
>
> > rectangle = new Shape();
> > }
>
> > public override function getDefaultPane(map:IMap):IPane
> > {
> > return map.getPaneManager().getPaneById(PaneId.PANE_OVERLAYS);
> > }
>
> > public function getLatLngs():Array {
> > return latlngs;
> > }
>
> > public function getPoints():Array {
> > var points:Array = new Array(latlngs.length);
> > for (var i:int=0; i<latlngs.length; i++) {
> > points[i] =
> > matrix.transformPoint(latlngToPoint(LatLng(latlngs
> > [i])));
> > }
> > return points;
> > }
>
> > public override function positionOverlay(zoomChanged:Boolean):void
> > {
> > rectangle.graphics.clear();
> > rectangle.graphics.beginFill(Color.BLUE, .5);
>
> > var points:Array = getPoints();
> > var point:Point = Point(points[0]);
> > rectangle.graphics.moveTo(point.x, point.y);
> > for (var i:int=0; i<points.length; i++) {
> > point = Point(points[(i + 1) % points.length])
> > rectangle.graphics.lineTo(point.x, point.y);
> > }
> > rectangle.graphics.endFill();
>
> > addChild(rectangle);
> > }
>
> > private function latlngToPoint(latlng:LatLng):Point {
> > return pane.fromLatLngToPaneCoords(latlng);
> > }
>
> > private function pointToLatLng(point:Point):LatLng {
> > return pane.fromPaneCoordsToLatLng(point);
> > }
> > }
>
> --
> =============
> Juguang XIAO
> Beijing, China
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Google Maps API For Flash" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-maps-api-for-flash?hl=en
-~----------~----~----~----~------~----~------~--~---