Jun 2, 2011

Drawing on a Google Map in Adobe Flex

    Not too long ago I had cause to add drawing capabilities to a Google map in my Adobe Flex project.  Seems like this would be a pretty common use of the Google map, but I never saw any simple tutorials that covered it.  So in an effort share the knowledge I put together this simple tutorial and example explaining how to allow users to draw on your Google map.

The Example

  • Click the “Rectangle” button to be able to draw a rectangle via click-dragging with the mouse.
  • Click the “Normal” button to return the Google map to normal mode, e.g. click-drag causes the map to pan.

    Source can be downloaded at Source

The Code


<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
         xmlns:s="library://ns.adobe.com/flex/spark"
         xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="500" minHeight="500">
 
  <s:Panel width="500" height="500">
    <s:controlBarContent>
      <s:Button label="Normal" click="normalMode_clickHandler(event)"/>
      <s:Button label="Rectangle" click="drawRectMode_clickHandler(event)"/>
    </s:controlBarContent>
   
    <maps:Map id="googleMap"
          xmlns:fx="http://ns.adobe.com/mxml/2009"
          xmlns:s="library://ns.adobe.com/flex/spark"
          xmlns:mx="library://ns.adobe.com/flex/mx"
          xmlns:maps="com.google.maps.*"
          key = "ABQIAAAA101ZpCe0E26wnsiqJEgD_RTwM0brOpm-All5BF6PoaKBxRWWERSYGRVfMM1lrbUkZX4ThSHMM7BgEA"
          sensor="false"
          width="100%"
          height="100%">
 
    </maps:Map>
   
  </s:Panel>
 
  <fx:Script>
    <![CDATA[
      import com.google.maps.LatLng;
      import com.google.maps.MapMouseEvent;
     
      /**
       * Will store the lat long of where the mouse was clicked
       * while in drawing mode.  Will be NULL if not actively
       * drawing.
       */

      private var _mouseDownLatLng:LatLng;
     
      /**
       * The rectangle being actively drawn due to a
       * drag mouse action when in drawing mode.
       */

      private var _drawingPolygon:RectangleOverlay = null;

      /**
       * Handler called when the user presses the "Normal" mode button.
       */

      protected function normalMode_clickHandler(event:MouseEvent):void
      {
        stopDrawingMode();
      }

      /**
       * Handler called when the user presses the "Rectangle" mode button.
       */

      protected function drawRectMode_clickHandler(event:MouseEvent):void
      {
        startDrawingMode();
      }
     
      /**
       * Enabling drawing mode means
       * 1.  Turning OFF normal map mouse operations
       * 2.  Attaching custom handlers for map mouse events
       */

      private function startDrawingMode() :void
      {
        googleMap.disableDragging();
        googleMap.disableScrollWheelZoom();
        googleMap.disableContinuousZoom();
        googleMap.addEventListener(MapMouseEvent.MOUSE_DOWN, onGMapMouseDown);
        googleMap.addEventListener(MapMouseEvent.MOUSE_MOVE, onGMapMouseMove);
        googleMap.addEventListener(MapMouseEvent.MOUSE_UP, onGMapMouseUp);
      }
     
      /**
       * Enabling drawing mode means
       * 1.  Turning ON normal map mouse operations
       * 2.  Removing custom handlers for map mouse events
       */

      private function stopDrawingMode():void
      {
        googleMap.enableDragging();
        googleMap.enableScrollWheelZoom();
        googleMap.disableContinuousZoom();
        googleMap.removeEventListener(MapMouseEvent.MOUSE_DOWN, onGMapMouseDown);
        googleMap.removeEventListener(MapMouseEvent.MOUSE_MOVE, onGMapMouseMove);
        googleMap.removeEventListener(MapMouseEvent.MOUSE_UP, onGMapMouseUp);
      }
     
      /**
       * Called when the mouse is clicked while in drawing mode.
       * Saves the _mouseDownLatLng of where the mouse was clicked
       * and draws the rectangle.
       */

      private function onGMapMouseDown(event:MapMouseEvent):void
      {
        _mouseDownLatLng = event.latLng; 
        drawRectangle(_mouseDownLatLng, _mouseDownLatLng);
      }
     
      /**
       * Called when the mouse is moved while dragging in drawing
       * mode.  Draws a rectangle from the mouse down point to
       * the current mouse location.
       */

      private function onGMapMouseMove(event:MapMouseEvent):void
      {
        if(_mouseDownLatLng != null)
        {
          var curLatLng:LatLng = event.latLng;
          drawRectangle(_mouseDownLatLng, curLatLng);
        }
      }
     
      /**
       * Called when the mouse button is release while dragging
       * in drawing mode.  Resets the mouse down point, and the
       * actively drawing polygon.
       */

      private function onGMapMouseUp(event:MapMouseEvent):void
      {
        _mouseDownLatLng = null;
        if(_drawingPolygon != null)
        {
          _drawingPolygon = null;
        }
      }
     
      /**
       * Effectively updates the "_drawingPolygon" by removing it
       * and setting it to the new coordinates.
       */

      private function drawRectangle(start:LatLng, end:LatLng):void
      {
        if(_drawingPolygon != null)
        {
          googleMap.removeOverlay(_drawingPolygon);
          _drawingPolygon = null;
        }
       
        var rectangle:RectangleOverlay = new RectangleOverlay(start, end);
        _drawingPolygon = rectangle;
        googleMap.addOverlay(_drawingPolygon);
      }

    ]]>
  </fx:Script>
</s:Application>  

 

 

How it works

    The code is actually very simple.  The Google map throws it’s own custom mouse events that include the Lat/Lon coordinates of the mouse click.  The code simply attaches listeners to those mouse events which then creates a rectangle from the mouse down point, to the current mouse point.  The only non-obvious aspect of the demo is how the polygon is made to look like it is stretching with the mouse movements.  At the time I originally wrote this code, the version of Google maps I was using didn’t allow you to modify a polygon.  So to simulate the polygon moving and stretching with the mouse I would remove the old polygon from the map, create new polygon with the new coordinates, and add the new polygon to the map.  Ba-da-bing it looks like the rectangle is stretching with the mouse.  
Please leave a comment or drop me an email if you found this post helpful.

I hope this was helpful.  Please leave comments or shoot me an email: plummeronsoftware at gmail dot com.

13 comments:

Hua Cai said...

ray-ban sunglasses
louis vuitton bags
michael kors outlet online
lululemon uk
louis vuitton outlet
swarovski outlet
louis vuitton outlet stores
michael kors factory outlet
burberry outlet
mulberry outlet
hermes outlet store
ray ban sunglasses
michael kors handbags
cheap oakley sunglasses
hermes outlet
air max 2015
fitflops outlet sale
louis vuitton handbags
ferragamo outlet
tiffany and co
nike tn pas cher
rolex uk
mulberry sale
replica watches
bottega veneta outlet online
cheap michael kors handbags
fitflops clearance
toms shoes
christian louboutin outlet
chaussure louboutin
celine outlet online
toms outlet
cheap jordan shoes
nike blazer pas cher
ferragamo outlet
20160528caihuali

xumeiqing said...

20160620meiqing
sac longchamp pliage
coach factory outlet
coach outlet
coach factory outlet
adidas nmd runner
converse shoes
burberry outlet
fitflops sale clearance
nike roshe run women
fitflops
gucci handbags
burberry outlet
ray ban outlet
cheap oakley sunglasses
ray ban sunglasses
louis vuitton outlet
burberry outlet
asics outlet
yeezy boost 350
reebok uk
ray bans
hermes belt
kate spade outlet
canada goose
holliste sale
cartier watches
yeezy boost 350 black
michael kors outlet
nike trainers
chaussure louboutin
kate spade outlet
christian louboutin shoes
louis vuitton factory outlet
nike free flyknit 4.0
bottega veneta handbags
running shoes
reebok pump

xjd7410@gmail.com said...

discount jordans
air jordans
coach factory outlet
retro 11
louboutin shoes
ray ban sunglasses
kobe 8
rolex watches
giuseppe zanotti
oakley sunglasses
adidas running shoes
tiffany jewelry
adidas superstar trainers
gucci handbags
louis vuitton purses
lebron 12
louis vuitton outlet
burberry handbags
air jordan femme
timberland outlet
michael kors outlet online
michael kors outlet
nike store
coach outlet online
ray ban sunglasses
fit flops
coach factory outlet online
louis vuitton handbags
supra for sale
coach outlet online
chenyingying712

dong dong23 said...

san antonio spurs jerseys
christian louboutin sale
air jordan pas cher
burberry outlet
moncler pas cher
ugg sale
louis vuitton
michael kors outlet
sac longchamp
jordan shoes
201610.6wengdongdong

raybanoutlet001 said...

michael kors outlet clearance
ralph lauren pas cher
rolex replica watches
ecco shoes
instyler max
nike roshe run
ed hardy outlet
nike huarache
nike free 5
michael kors handbags wholesale

raybanoutlet001 said...

michael kors handbags
moncler outlet
michael kors outlet clearance
nike tn
golden state warriors
dolce and gabbana
pandora outlet
chicago bears jerseys
louis vuitton pas cher
jordan shoes

dada24 Xu said...

louis vuitton pas cher
hermes bags
pandora charms sale clearance
cheap jordans for sale
longchamp handbags
uggs
moncler outlet online
canada goose
adidas nmd r1
kd shoes
zhi20161209

dong dong23 said...

basketball shoes
michael kors outlet online
louis vuitton outlet
adidas yeezy 350
tods shoes
washington wizards jerseys
ugg outlet
canada goose clothing
toms shoes
michael kors outlet online
201612.27wengdongdong

dong dong23 said...

basketball shoes
michael kors outlet online
louis vuitton outlet
adidas yeezy 350
tods shoes
washington wizards jerseys
ugg outlet
canada goose clothing
toms shoes
michael kors outlet online
201612.27wengdongdong

Meiqing Xu said...

moncler outlet
michael kors outlet
beats by dr dre
coach factory outlet
adidas shoes
longchamp outlet
gucci purses
omega replica watches
beats earbuds
the north face
20170209CAIYAN

Meiqing Xu said...

moncler outlet
michael kors outlet
beats by dr dre
coach factory outlet
adidas shoes
longchamp outlet
gucci purses
omega replica watches
beats earbuds
the north face
20170209CAIYAN

adidas nmd said...

ugg outlet
true religion outlet store
oakley sunglasses
kobe 9
michael kors handbags
mont blanc outlet
ugg outlet
nike blazer pas cher
ugg boots
michael kors handbags

aaa kitty20101122 said...

nmd
kobe shoes
michael kors handbags
nmd
adidas tubular
nike air zoom
fitflops
adidas ultra
prada sunglasses
longchamp bags