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
-~----------~----~----~----~------~----~------~--~---

Reply via email to