Project AgsPoint (spatial reference 4326 to spatial reference 102100)

8339
26
10-18-2010 08:52 AM
KOLDODUARTE
New Contributor
Hi all

We need to project the x and y obtained from the ESRI_Places_World/GeocodeServer and show it as a graph into a base map with spatial reference 102100.

We tested with:

AGSPoint *pt = addressCandidate.location;
AGSMutablePoint *newPoint = [AGSMutablePoint pointWithX:pt.x y:pt.y spatialReference:self.mapView.spatialReference];


But this not works.

Do you have any idea?

BR,
Koldo
0 Kudos
26 Replies
LucaAlferi1
New Contributor
below formula converts 4326 latitude to 102100 latitude

+ (double)toWebMercatorY:(double)latitude
{
double rad = latitude * 0.0174532;
double fsin = sin(rad);

double y = 6378137 / 2.0 * log((1.0 + fsin) / (1.0 - fsin));

return y;
}

below formula converts 4326 longitude to 102100 longitude
+ (double)toWebMercatorX:(double)longitude
{
double x = longitude * 0.017453292519943 * 6378137;

return x;
}

See my attachment , it contains a utility mercator convertor . You can simply import the class in your project and call the above static methods on it
I have tried it with location manager and it works!!!
Regards,
Harikant Jammi


Hi Jammi.
I'm a beginner of objective-C. How can use your fantastic code in my code:
- (void)locator:(AGSLocator *)locator operation:(NSOperation *)op didFindLocationsForAddress:(NSArray *)candidates{
    
    //check and see if we didn't get any results
 if (candidates == nil || [candidates count] == 0){
        //show alert if we didn't get results
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Informazione" message:@"Nessun risultato trovato" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        [alert release];
 }
 else {
        //use these to calculate extent of results
        double xmin = DBL_MAX;
        double ymin = DBL_MAX;
        double xmax = -DBL_MAX;
        double ymax = -DBL_MAX;
  
  //create the callout template, used when the user displays the callout
  self.calloutTemplate = [[[AGSCalloutTemplate alloc]init] autorelease];
        
        //loop through all candidates/results and add to graphics layer
  for (int i=0; i<[candidates count]; i++){            
   AGSAddressCandidate *addressCandidate = (AGSAddressCandidate *)[candidates objectAtIndex:i];
            
            //get the location from the candidate
            AGSPoint *pt = addressCandidate.location;
            
            //accumulate the min/max
            if (pt.x  < xmin)
                xmin = pt.x;
            
            if (pt.x > xmax)
                xmax = pt.x;
            
            if (pt.y < ymin)
                ymin = pt.y;
            
            if (pt.y > ymax)
                ymax = pt.y;
          
 //create a marker symbol to use in our graphic
            AGSPictureMarkerSymbol *marker = [AGSPictureMarkerSymbol pictureMarkerSymbolWithImageNamed:@"BluePushpin.png"];
            marker.xoffset = 9;
            marker.yoffset = -16;
            marker.hotspot = CGPointMake(-9, -11);
            //set the text and detail text based on 'Name' and 'Descr' fields in the attributes
            self.calloutTemplate.titleTemplate = self.searchBar.text;
            //create the graphic
    AGSGraphic *graphic = [[AGSGraphic alloc] initWithGeometry: pt symbol:marker attributes:[[addressCandidate.attributes mutableCopy] autorelease] infoTemplateDelegate:self.calloutTemplate];
            
            
            //add the graphic to the graphics layer
            
   [self.graphicsLayer addGraphic:graphic];
            
            if ([candidates count] == 1)
            {
                //we have one result, center at that point
                [self.mapView5 centerAtPoint:pt animated:NO];
                
    // set the width of the callout
    self.mapView5.callout.width = 250;
                
                //show the callout
                [self.mapView5 showCalloutAtPoint:(AGSPoint *)graphic.geometry forGraphic:graphic animated:YES];
            }
   
   //release the graphic bb  
   [graphic release];            
  }
        
        //if we have more than one result, zoom to the extent of all results
        int nCount = [candidates count];
        if (nCount > 1)
        {            
            AGSMutableEnvelope *extent = [AGSMutableEnvelope envelopeWithXmin:xmin ymin:ymin xmax:xmax ymax:ymax spatialReference:self.mapView5.spatialReference];
            [extent expandByFactor:1.5];
   [self.mapView5 zoomToEnvelope:extent animated:YES];
        }
 }
    
    //since we've added graphics, make sure to redraw
    [self.graphicsLayer dataChanged];
    
}


Thanks
0 Kudos
NimeshJarecha
Esri Regular Contributor
If you want to convert between WGS 1984 (4326) and Web Mercator (102100) then use AGSGeometryGeographicToWebMercator() and AGSGeometryWebMercatorToGeographic() functions.

Regards,
Nimesh
0 Kudos
MuruganandhamKuppan1
New Contributor III

Hi,

These methods are not accessible in runtime SDK 100.x. how can i achieve this?

Regards,

0 Kudos
Nicholas-Furness
Esri Regular Contributor
0 Kudos
MuruganandhamKuppan1
New Contributor III

Yes i found that. Lot of stuffs in that class. Thanks Nick.

0 Kudos
GregNichols
New Contributor II
I had a similar problem, and found a soltuion that might help.    I needed to project a mapPoint from 102100 to other systems using the GeometryService.Project, however this would consistently return a mapPoint with NaN coordinates.   The solution was to first check that the map point is in 102100, if so pass this to the WebMercatorUtil.webMercatorToGeographic to get a latlong mappoint.   Then use the geometry service to project this latlong mapPoint into whatever other coordsystem I needed.   BTW, I'm working with the API for Flex.

-Greg Nichols, TAIC
0 Kudos
VijayPatel1
New Contributor
@ harikant_jammi

Thats it...
really working...
Thank you very much.. you save my lots of work...
0 Kudos