Pixel based distances

6037
5
03-05-2011 09:31 PM
AliJoudeh
New Contributor
I need to draw a 50 KM diameter circle on various map scales/zoom levels without having to use any services.

I'm unable to decide what pixel diameter represents 40 KM!!!

So the question is, how do I draw a 40KM diameter circle!???

Please help
Tags (2)
0 Kudos
5 Replies
Drew
by
Occasional Contributor III
What do you mean by "not using any services"?

If you are using ArcGIS Server, I suggest using the geometry service to buffer a location by 50 KM.
Buffer sample:
http://help.arcgis.com/en/webapi/flex/samples/index.html?sample=BufferSample
0 Kudos
AndrewThomas
New Contributor II
Is there an easy way of converting map units to screen units and vice versa?

What I am trying to achieve is a buffer distance of 10 pixels, no matter what scale. So when zoomed right in, 10 pixels might be 10 meters, but further out 10 pixels might be 10 kilometres.

I created a function along the lines of:

  private function calculateDistanceFromPixels(pixels:int):Number{   
   var mapCenter:MapPoint = MapPoint(map.extent.center);
   var mapScreenCenterPoint:Point = map.toScreen(mapCenter);
   var lengthPolyLine:Polyline = new Polyline(null,map.spatialReference);
   lengthPolyLine.addPath([mapCenter,map.toMap(new Point(mapScreenCenterPoint.x+pixels,mapScreenCenterPoint.y))]);
   return lengthPolyLine.extent.width; 
  }


but there may be a simpler way????

As an aside, I'm doing this because I want to identify by line to pick up nearby points - which the current rest interface doesn't support - the tolerance parameter does nothing. (To a web map user, a line going through a point symbol should pick up that point)

I.E imagine a point was at X: 120000.123456,Y:540000.654321 in an imaginary coord sys. Using the identify on a MapService using geometry path ,  (The last y values is 0.000001 different from the point) will never pick up the point no matter what the tolerance value is, the path would have to exactly cross the point. Try it if you don't believe me.

Identify by point does seem to take tolerance into account - why points and not lines?
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Andrew,

  I don't know if this is any better but here is another way:

            private function calculateDistanceFromPixels(tolerance:Number):Number
            {
                var screenPoint:Point = map.toScreen(map.extent.center);
                
                var upperLeftScreenPoint:Point = new Point(screenPoint.x - tolerance, screenPoint.y - tolerance);
                var lowerRightScreenPoint:Point = new Point(screenPoint.x + tolerance, screenPoint.y + tolerance);
                
                var upperLeftMapPoint:MapPoint = map.toMap(upperLeftScreenPoint);
                var lowerRightMapPoint:MapPoint = map.toMap(lowerRightScreenPoint);
                
                var ext:Extent = new Extent(upperLeftMapPoint.x, upperLeftMapPoint.y, lowerRightMapPoint.x, lowerRightMapPoint.y, map.spatialReference);
                return ext.width;
            }
GregoryKramida
New Contributor
I'm betting you're using a Mercator projection, so the "40 km circle" won't in fact be a circle. You can approximate with an ellipse that uses the proposed distance function to determine the length of semi-minor and semi-major axes.
0 Kudos
GregoryKramida
New Contributor
Okay, sorry, didn't notice other formulas weren't any good.
Here's a more practical description.

You can use the following pseudocode and develop functions to convert WGS Lat/Lon to WGS Mercator and back:
project_wgs_to_mercator(lon,lat){
   x := lon * 111319.490793241; 
   y := ln(tan((90 + lat) * 0.00872664625997167)) * 6378137.0000033; 
}


project_mercator_to_wgs(x,y){
   lon := x / 111319.49079323905;
   lat := 114.591559026167 * atan(exp(y * pi() / 20037508.3428)) - 90;
}


That should be accurate enough to how ESRI does it within micrometers.

The next thing you probably want to do is figure out WGS coordinates of some point within geo-distance of some central point. I recommend to look into Lambert formula, see how to invert it and get the coord based on the bearing. Should be accurate to within meters.

Finally, you want to make a POLYGON-type geometry, with the only ring being a set of points within this distance (i.e. 40 km) of the central point but with a different bearing (remember to convert WGS to WGS Mercator as you're doing it, and then just slap it onto your separate selection GraphicLayer or whatever have you as a Graphic.

Hope that helps.
0 Kudos