Hi,

At least for markers (not polylines but same technique can apply), we
have used the excellent technique developped by marko_rautajoki for
that. It is much much faster than core Google Maps Markers, and take 2
to 3 times less memory (indeed low perfs of native Google Maps markers
is mainly due to the huge amount of memory required by each marker,
average 50K per marker !). See this post :
http://groups.google.com/group/google-maps-api-for-flash/browse_thread/thread/52dc36c1a82ba119/22324304b29a1aed?lnk=gst&q=marko_rautajoki#22324304b29a1aed

or directly the example source code there, by viewing source of the
example : 
http://www.elisanet.fi/marko_rautajoki/overlaygrouping/bin-release/gmapPerformanceTest4.html

However we have some small issues to solve when using this technique
if you want to implement drag/drop, roll over, tooltips, etc. You need
to rewrite your own marker class, and then subclass it for concrete
use. It is not so complex. Here's is an example of what you can do for
this abstract class, took from our own code. Note that some of the
code (mouse events on markers) was also written to workaround a google
maps with AIR bug described there : 
http://code.google.com/p/gmaps-api-issues/issues/detail?id=1866

        public class VFMarker extends Sprite
        {
                public static var MARKER_DRAG_START:String = 
"VFMarker.DragStart";
                public static var MARKER_DRAG_STOP:String = "VFMarker.DragStop";
                public static var MARKER_DRAG_STEP:String = "VFMarker.DragStep";
                public static var MARKER_CLICK:String = "VFMarker.Click";
                public static var MARKER_DOUBLE_CLICK:String =
"VFMarker.DoubleClick";
                public static var MARKER_ROLL_OVER:String = "VFMarker.RollOver";
                public static var MARKER_ROLL_OUT:String = "VFMarker.RollOut";
                public static var DRAG_START_EVENT_CODE:uint = 0x01;
                public static var DRAG_STOP_EVENT_CODE:uint = 0x02;
                public static var CLICK_EVENT_CODE:uint = 0x04;
                public static var DOUBLE_CLICK_EVENT_CODE:uint = 0x08;
                public static var DRAG_STEP_EVENT_CODE:uint = 0x10;
                public static var ROLL_OVER_EVENT_CODE:uint = 0x20;
                public static var ROLL_OUT_EVENT_CODE:uint = 0x40;

                private static var _markerClicked:VFMarker=null; // the last 
marker
clicked (to block mose map clicks)
                private static var _iconList:Array = new Array; // the list of
different colored version of the marker, this is for optimisatino
purpose (avoiding recoloring each marker individually)
                private static var _displayToolTips:Boolean = false; // if true,
tooltips will be displayed. If false tooltip text is display in window
status label
                private static var _draggingMarker:VFMarker = null; // internal
variable to detect when dragging has really started

                private var _latLng : LatLng; // marker current position on the 
map
                private var _vo:IVOWithMarkers; // the associated VO of the 
marker
(e.g. Employee, Site, etc.)
                private var _pane:Pane; // the pane on which the marker is
                private var _listenEventsCodes:uint; // the list of events that 
we
want to follow for this marker
                private var _toolTip:ToolTipOverlay; // the tooltip associated 
to
the marker
                private var _toolTipText:String; // the current tooltip text of 
the
marker
                private var _draggable:Boolean = false; // if marker is 
draggable or
not
                private var _offset:Point; // (to top left)the offset for this
marker (to adjust latLng real position and where the marker is drawn,
equivalent to MarkerOptions.ALIGN constants
                private var _selected:Boolean = false; // if selected this will
change marker
                private var _window:VFNativeWindow;// the mapView window in 
which
the marker is
                private var _toolTipToogle:Boolean;// this to avoid toolTip 
blinking
                private var _emitDragStep:Boolean = false;//if true emit 
dragStep
event
                private var _wasDraggingTime:int=0; // to avoid markerClicks 
just
after dragging
                private var _color:uint=Color.WHITE;// curent marker color

                public function
VFMarker(aVO:IVOWithMarkers,aLatLng:LatLng,pane:Pane=null,listenEvents:uint=0)
{
                        latLng = aLatLng;
                        _vo = aVO;
                        _vo.addMarker(this);
                        _listenEventsCodes = listenEvents;
                        _pane=pane;
                        _window = pane.mapViewVO.window;
                        _selected = aVO.selected; // this to reflect selection 
status of
markers of a vo at pane load time
                        if (aVO.selected) _pane.selectVO(aVO); // to store the 
selected VO
on pane
                        refreshToolTipText();
                        buttonMode = true; // this allow to have the hand 
cursor when roll
over on the marker.
                        offset=new Point(-16,-16); // by default marker center. 
Should be
overriden most of time
                        _color=Color.WHITE;

                        // enable listeners depending on listenEvents table
                        if (listenEvents&DRAG_START_EVENT_CODE) {
                                
this.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownOnMarker);
                        }
                        if (listenEvents&DRAG_STOP_EVENT_CODE) {
                                
this.addEventListener(MouseEvent.MOUSE_UP,mouseUpOnMarker);
                        }
                        if (listenEvents&DOUBLE_CLICK_EVENT_CODE) {
                                
this.addEventListener(MouseEvent.DOUBLE_CLICK,markerDoubleClick);
                        }
                        if (listenEvents&CLICK_EVENT_CODE) {
                                
this.addEventListener(MouseEvent.CLICK,markerClick);
                        }
                        _emitDragStep = 
((listenEvents&DRAG_STEP_EVENT_CODE)!=0);
                        
this.addEventListener(MouseEvent.MOUSE_OVER,onMouseOver);
                        this.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut);

                }

                /**
                 * called when marker is removed, to remove the listeners
                 *
                 */
                public function onRemove():void {
                        if (_listenEventsCodes&DRAG_START_EVENT_CODE)
this.removeEventListener(MouseEvent.MOUSE_DOWN,mouseDownOnMarker);
                        if (_listenEventsCodes&DRAG_STOP_EVENT_CODE)
this.removeEventListener(MouseEvent.MOUSE_UP,mouseUpOnMarker);
                        if (_listenEventsCodes&CLICK_EVENT_CODE)
this.removeEventListener(MouseEvent.CLICK,markerClick);
                        if (_listenEventsCodes&DOUBLE_CLICK_EVENT_CODE)
this.removeEventListener(MouseEvent.DOUBLE_CLICK,markerDoubleClick);
                        
this.removeEventListener(MouseEvent.MOUSE_OVER,onMouseOver);
                        
this.removeEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
                        _vo.removeMarker(this); // to maintain markers 
collections in vos
(Employee, POIs)

                }

                /**
                 * Call when change the name
                 *
                 */
                public function refreshToolTipText():void {

                }

                // display tooltip. override this to do other things
                protected function onMouseOver(event:MouseEvent):void {
                        if (_displayToolTips) {
                                if (!_toolTip) {
                                        _toolTip = new 
ToolTipOverlay(latLng,_toolTipText);
                                        gpane.addOverlay(_toolTip);
                                }
                                _toolTipToogle= false;
                        } else {
                                _window.setStatusLabel(_toolTipText);
                        }
                        if
((_listenEventsCodes&ROLL_OVER_EVENT_CODE)==ROLL_OVER_EVENT_CODE) {
                                sendEvent(MARKER_ROLL_OVER,latLng);
                        }

                }

                // remove tooltip. override this to do other things
                protected function onMouseOut(event:MouseEvent):void {
                        if (_displayToolTips) {
                                if (_toolTip) {
                                        if (_toolTipToogle) {
                                                gpane.removeOverlay(_toolTip);
                                                _toolTip = null;
                                        } else {
                                                _toolTipToogle= true;
                                                var timer:Timer = new 
Timer(1000,1);
                                                
timer.addEventListener(TimerEvent.TIMER,function
(e:TimerEvent):void {
                                                        if (_toolTip) {
                                                                
gpane.removeOverlay(_toolTip);
                                                                _toolTip = null;
                                                        }
                                                });
                                                timer.start();
                                        }
                                }
                        } else {
                                if (!draggingMarker) {
                                        _window.setStatusLabel("");
                                }
                        }
                        if 
((_listenEventsCodes&ROLL_OUT_EVENT_CODE)==ROLL_OUT_EVENT_CODE)
{
                                sendEvent(MARKER_ROLL_OUT,latLng);
                        }
                }

                // send event markers into application.
                private function sendEvent(eventName:String,latLng:LatLng):void
                {
                        dispatchEvent(new VFMarkerEvent(eventName,this,latLng));
                }

                /**
                 * the base icon, that will be eventually colored, then getIcon 
may
draw additional things on top of icon
                 * @return
                 *
                 */
                protected function getIconBase():Bitmap {
                        return new Bitmap();
                }

                /**
                 * get the icon of the marker.
                 * will color the marker with passed fillstyle, if any
                 * @param fillStyle
                 * @return
                 *
                 */
                public function getIcon(afillStyle:VFFillStyle=null):Bitmap {
                        var resultIcon:Bitmap = getIconBase();
                        var objectKey:ByteArray = new ByteArray();
                        if (!afillStyle) { afillStyle = new VFFillStyle(); 
afillStyle.color
= _color;} // if no fillstyle, use previous color (it is a refresh on
select or unselect)
                        //change icon color, if different from white
                        if (afillStyle.color!=Color.WHITE || 
afillStyle.colors.length>1) {
                                _color = afillStyle.color;
                                // build icon key : the icon class name + color 
: if same class
name and color, do not recolorize (it takes time).
                                
objectKey.writeObject(Object(resultIcon).constructor.toString());
                                if (afillStyle.colors.length<=1) {
                                        afillStyle.colors=[_color];
                                }
                                objectKey.writeObject(afillStyle.colors);
                                //do not change color for each icon, but only 
for each new Icon
with a new fillstyle

                                if (_iconList[objectKey]==null) {
        
UtilityFunctions.changeIconFillColor(Bitmap(resultIcon).bitmapData,afillStyle.colors,Number(afillStyle.alpha));
                                        _iconList[objectKey] = 
Bitmap(resultIcon).bitmapData; // store
new colored icon in dictionary

                                }
                                resultIcon.bitmapData 
=_iconList[objectKey].clone();    // must clone
as it is different instances of bitmap data
                        }
                        return resultIcon;
                }

                /**
                 * recompute the marker position (x,y) on positionWatcher, 
according
to latLng
                 *
                 */
                public function computeMarkerPosition():void {
                        var position : Point;
                        if (!pane.is3D) {
                                position = pane.gpane.fromLatLngToPaneCoords( 
latLng );
                        } else {
                                position = 
pane.positionWatcher.getPointForLatLng3D( latLng );
                        }
                                x = position.x+offset.x;
                                y = position.y+offset.y;
                }

                /**
                 * recompute latLng according to point
                 *
                 */
                public function computeLatLngFromPoint():void {


                        if (pane.is3D) {
                                latLng = 
pane.positionWatcher.getLatLngForPointIn3DMap(point);
                        } else {
                                latLng = 
pane.gpane.fromPaneCoordsToLatLng(point);
                        }
                }

                /**
                 * call this to redraw the marker if icon or style changes.
                 * @param fillStyle
                 *
                 */
                public function
refresh(fillStyle:VFFillStyle=null,size:uint=32):void {
                        var g : Graphics = this.graphics;
                        g.clear();      //to clear the garphics before drawing.
                        
g.beginBitmapFill(getIcon(fillStyle).bitmapData,null,false);
                        g.drawRect( 0, 0, size, size );         //draw the 
bitmap in the
rectangle
                        g.endFill();    //end draw the bitmap
                        if (_selected) {        //If the marker is selected, 
draw a circle out of
the bitmap
                                g.lineStyle(2,0,1,true);
                                g.drawCircle(size/2-1,size/2-1,size/2-2);
                        }
                }

                public function select():void {
                        if (!_selected) {
                                _selected = true;
                                refresh();

                                if (pane.positionWatcher.numChildren>0 &&
(pane.markers.indexOf(this)>=0)) { // must be added already on pane
        
pane.positionWatcher.setChildIndex(this,pane.positionWatcher.numChildren-1); //
put it in front
                                }
                        }
                }

                public function unselect():void {
                        if (_selected) {
                                FSTrace.fsTrace("marker unselect "+vo.name+" 
"+vo.latLng+" pane
"+pane.name);
                                _selected = false;
                                refresh();
                        }
                }

                // start dragging the marker (in reality drag really start at 
the
first MOUSE_MOVE
                protected function mouseDownOnMarker(event:MouseEvent):void {
                        _markerClicked = this;
                        if (_draggable) {
                                        _draggingMarker=null;
                                        
addEventListener(MouseEvent.MOUSE_MOVE,onDuringDrag);
                                        startDrag();
                        }
                }

                // to detecte real start of dragging
                protected function onDuringDrag(event:MouseEvent):void {
                        if (!_draggingMarker) {
                                _draggingMarker = this;
                                sendEvent(MARKER_DRAG_START,latLng);
                        } else {
                                var aLatLng:LatLng = 
gpane.fromPaneCoordsToLatLng(new
Point(event.stageX,event.stageY));
                                _window.setStatusLabel("Lat : 
"+aLatLng.lat().toFixed(6)+" Lng :
"+aLatLng.lng().toFixed(6));
                                if (_emitDragStep) {
                                        sendEvent(MARKER_DRAG_STEP,aLatLng);
                                }
                        }
                }
                // end of dragging
                protected function mouseUpOnMarker(event:MouseEvent):void {
                        FSTrace.fsTrace("mouseUpOnMarker "+latLng+" x "+x+" y 
"+y+"
event.localX "+event.localX+" event.localY "+event.localY);
                        stopDrag();
                        removeEventListener(MouseEvent.MOUSE_MOVE,onDuringDrag);
                        if (_draggingMarker) {
                                _window.setStatusLabel("");
                                _draggingMarker=null;
                                _markerClicked=null;
                                _wasDraggingTime=getTimer();
                                latLng = gpane.fromPaneCoordsToLatLng(new
Point(event.stageX,event.stageY));
                                sendEvent(MARKER_DRAG_STOP,latLng);
                        }
                }
                // this to correct a bug somtimes the mouseUp on marker is not
detected, replaced by a mouseUp on map
                public function triggerMouseUp(event:MouseEvent):void {
                        mouseUpOnMarker(event);
                }

                /**
                 * @param event the MapMouseEvent.
                 */
                protected function markerClick(event:MouseEvent):void {
                        if ((getTimer()-_wasDraggingTime)>500) { // to avoid 
marker click
events at the end of dragging
                                FSTrace.fsTrace("VFMarker.markerClick");
                                _markerClicked = this;
                                sendEvent(MARKER_CLICK,latLng);
                        }
                }
                /**
                 * @param event the MapMouseEvent.
                 */
                protected function markerDoubleClick(event:MouseEvent):void {
                        sendEvent(MARKER_DOUBLE_CLICK,latLng);
                }

                /****************************************** ACCESSORS
********************************/
                public function get toolTip():ToolTipOverlay
                {
                        return _toolTip;
                }

                public function set toolTip(value:ToolTipOverlay):void
                {
                        _toolTip = value;
                }

                public function get vo():IVOWithMarkers
                {
                        return _vo;
                }

                public function set vo(value:IVOWithMarkers):void {
                        _vo = value;
                }

                public function get gpane():IPane
                {
                        return _pane.gpane;
                }

                public function get pane():Pane {
                        return _pane;
                }

                public function get draggable():Boolean
                {
                        return _draggable;
                }

                public function set draggable(value:Boolean):void
                {
                        _draggable = value;
                }

                public function get latLng():LatLng
                {
                        return _latLng;
                }

                public function set latLng(value:LatLng):void
                {
                        _latLng = value;

                }

                public function get toolTipText():String
                {
                        return _toolTipText;
                }

                public function set toolTipText(value:String):void
                {
                        _toolTipText = value;
                }


                public function get offset():Point
                {
                        return _offset;
                }

                public function set offset(value:Point):void
                {
                        _offset = value;
                }

                public static function get markerClicked():VFMarker
                {
                        return _markerClicked;
                }

                public static function set markerClicked(value:VFMarker):void
                {
                        _markerClicked = value;
                }

                public function get selected():Boolean
                {
                        return _selected;
                }



                /**
                 * default menu data for contextual menu of markers
                 * need to override this
                 * @return
                 *
                 */
                public function get menuData():XML
                {
                        return null;
                }


                /**
                 * return true point position removing offset from marker x,y
                 * @return
                 *
                 */
                public function get point():Point {
                        return new Point(x-offset.x,y-offset.y);
                }

                public static function get displayToolTips():Boolean
                {
                        return _displayToolTips;
                }

                public static function set displayToolTips(value:Boolean):void
                {
                        _displayToolTips = value;
                }

                protected function get window():VFNativeWindow
                {
                        return _window;
                }

                public static function get draggingMarker():VFMarker
                {
                        return _draggingMarker;
                }


        }
}


Cédric NICOLAS
www.villefluide.fr


On 18 oct, 12:30, Engendrix <[email protected]> wrote:
> Hi there,
>
> I´m developing an app on AS3 and I need to place about 3000 of markers
> an 7000 connections  (polylines) between those markers. When I load
> just about 100 markers, the app runs ok but when I try to load all of
> them, it slows down and doesn´t work properly.
> I have already read some about markerManager, but I need all the
> markers to be shown in all zoom levels.
> Can anyone help me with this issue? I´m thinking of doing it in google
> Earth, but this will be start from the beginning agaim. Any Idea or
> suggestion?
>
> Thanks for your time.

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