Select to view content in your preferred language

Map coordinates to screen space?

1154
2
09-30-2010 12:31 PM
DavidElies
Deactivated User
Does anybody know how to map geographical coordinates and distances to screen coordinates in pixels?  I want to draw graphics at a size that correspond to actual distances on Earth.  For example, a 1km grid square.  It sure seems like it should be easy...but I can't figure it out.

Thanks!
Tags (2)
0 Kudos
2 Replies
DanJensen
Deactivated User
This may not be the easiest method, but it works if you want squares.  I am sure you can figure out how to adapt it to your requirements.  This app allows the user to specify the size and location of the graphic square.  Try this on one of your map services.

<?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:esri="http://www.esri.com/2008/ags"
        xmlns:mx="library://ns.adobe.com/flex/mx">

 <fx:Script>
  <![CDATA[
   import com.esri.ags.Graphic;
   import com.esri.ags.events.MapMouseEvent;
   import com.esri.ags.geometry.MapPoint;
   import com.esri.ags.geometry.Polygon;
   import com.esri.ags.geometry.Polyline;
   
   import mx.controls.Alert;

   protected function Map_mapClickHandler(event:MapMouseEvent):void
   {
    //allow user to enter size of square desired in map units
    if(tInput1.text == ""){
         Alert.show("Please enter a number in the text input before clicking the map.");
    }else{
     
     var size:int = Number(tInput1.text);
     var halfSize:Number = size/2;
     
     var center:MapPoint=Map.toMapFromStage(event.stageX, event.stageY);
     
     var botLeft:MapPoint = new MapPoint;
     //new mapPoint is assigned the same coor sys as the map
     botLeft.spatialReference=Map.spatialReference;
     //units defined by the spatial reference
     botLeft.x=center.x-halfSize;
     botLeft.y=center.y-halfSize;
     
     var botRight:MapPoint = new MapPoint;
     botRight.spatialReference=Map.spatialReference;
     botRight.x=center.x+halfSize;
     botRight.y=center.y-halfSize;
     
     var topRight:MapPoint = new MapPoint;
     topRight.spatialReference=Map.spatialReference;
     topRight.x=center.x+halfSize;
     topRight.y=center.y+halfSize;
     
     var topLeft:MapPoint = new MapPoint;
     topLeft.spatialReference=Map.spatialReference;
     topLeft.x=center.x-halfSize;
     topLeft.y=center.y+halfSize;
     
     var newPolygon:Polygon = new Polygon;
     newPolygon.spatialReference=Map.spatialReference;
     newPolygon.rings=[[botLeft, botRight, topRight, topLeft, botLeft]];
     
     var newGraphic:Graphic = new Graphic;
     newGraphic.geometry=newPolygon;
     newGraphic.symbol=symbol1;
     
     gLayer.add(newGraphic);
    }
   }


   protected function clearGraphics_clickHandler(event:MouseEvent):void
   {
    gLayer.clear();
   }

  ]]>
 </fx:Script>

 <fx:Declarations>
  <esri:SimpleFillSymbol id="symbol1"
               style="solid" color="0xFF0000" alpha="0.3">
   <esri:outline>
    <esri:SimpleLineSymbol style="solid" color="0x000000" width="1" />
   </esri:outline>
  </esri:SimpleFillSymbol>
 </fx:Declarations>
 
 <s:layout>
  <s:VerticalLayout gap="10" horizontalAlign="center"
     paddingBottom="20" paddingLeft="20" paddingRight="20" paddingTop="20"/>
 </s:layout>
 <s:BorderContainer id="mainBC"
   width="100%" height="100%"
   borderVisible="true" borderAlpha="1" borderColor="#FF0000"
                                      borderStyle="solid" borderWeight="3">
  <s:layout>
   <s:VerticalLayout horizontalAlign="center" verticalAlign="middle" paddingTop="5"/>
  </s:layout>
  <esri:Map id="Map" logoVisible="false" mapClick="Map_mapClickHandler(event)">
   <esri:ArcGISDynamicMapServiceLayer id="mapSvc" url="yourMapServiceURLHere"/>
   <esri:GraphicsLayer id="gLayer"/>
  </esri:Map>
 </s:BorderContainer>
 
 <s:TextInput id="tInput1" text="5000"/>
 <s:Button id="clearGraphics" label="Clear Graphics" click="clearGraphics_clickHandler(event)"/>
</s:Application>


Good Luck,
-Dan
0 Kudos
DavidElies
Deactivated User
Thanks, Dan.  I was able to adapt your code for my purposes.  Instead of using a Polygon, I just used an Extent since I was looking for a square anyway.  This simplified the process a bit:
protected function Map_mapClickHandler(event:MapMouseEvent):void
   {
    //allow user to enter size of square desired in map units
    if(tInput1.text == ""){
         Alert.show("Please enter a number in the text input before clicking the map.");
    }else{
     
     var size:int = Number(tInput1.text);
     var halfSize:Number = size/2;
     
     var center:MapPoint=Map.toMapFromStage(event.stageX, event.stageY);
     
     var extent:Extent = new Extent(center.x - halfSize,
               center.y - halfSize,
               center.x + halfSize,
               center.y + halfSize,
               map.spatialReference);
     
     var newGraphic:Graphic = new Graphic;
     newGraphic.geometry=extent;
     newGraphic.symbol=symbol1;
     
     gLayer.add(newGraphic);
    }
   }


This appears to be working for me.  Thanks again!  If anybody else has another idea, I'd still like to hear it.
0 Kudos