Select to view content in your preferred language

Project AgsPoint (spatial reference 4326 to spatial reference 102100)

9166
26
10-18-2010 08:52 AM
KOLDODUARTE
Emerging 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
HarikantJammi
Emerging 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
0 Kudos
DiveshGoyal
Esri Regular Contributor
Hi, Alberto,

I managed to reproduce the problem by modifying the GeocodingSample as you suggested.

Yes, the locations returned by the Geocode Service are still not correctly projected to 102100 even when using locationsForAddress:returnFields: outSpatialReference:. The reason is that the ability to specify an outSpatialReference was only added at 10 in the REST API. The service that you are hitting is still only 931 and it is ignoring your request to reproject the location.

I must also admit, we should have mentioned in the API ref doc that this functionality is only available with 10 servers. We will fix the omission.

In the meanwhile, you can use a different GeocodeService from a 10 server that provides this functionality, but if you want to continue using this particular service, you will have to reproject the point using other means.

Now, before you try to reproject the point, you must FIRST manually assign a spatial reference to the returned locations. This is because the service does not have a valid spatial reference (you can tell by looking at the services directory page) and consequently, the returned location dont have a spatial reference either.  I think  it is safe to assume that the returned locations are in WGS 84. So you must manually assign the result AGSPoint a spatial reference with WKID=4326. This is crucial because most geometry operations require your input geometries to have a spatial reference.

The SDK contains a global function called AGSGeometryWebMercatorToGeographic() that can help you convert from WGS84 to WebMercator if you don't want to use a Geometry Service.

Hope this helps.
BasemSaadawy
Deactivated User

This was very helpful for me and solved my problem of converting between coordinate systems.

Thank you.

0 Kudos
PaulJereb
Emerging Contributor
Hi technobrat,

I'm facing the same problem (my adressCandidate returns with spatialReference = Null) when using the Locator from http://tasks.arcgisonline.com/ArcGIS/rest/services/Locators/TA_Address_EU/GeocodeServer

I'd need to project it to WKID 31259... Any tip?

AGSSpatialReference* outSR = [AGSSpatialReference spatialReferenceWithWKID:31259  WKT:nil];
 
[self.locator locationsForAddress:addresses returnFields:outFields outSpatialReference:outSR];


The log-output for the returned candidate:
Candidate : AGSPoint: x = 15.441723, y = 47.067916, spatial reference: [(null)]



BR, Paul
0 Kudos
DiveshGoyal
Esri Regular Contributor
Paul,

You too will need to manually project the returned location (don't forget to assign it a spatial reference first though). The SDK doesn't have any convenient functions to convert to 31259. You'll have to use the AGSGeometryServiceTask.
0 Kudos
PaulJereb
Emerging Contributor
Divesh,

thanks for your reply. I tried to use the AGSGeometryServiceTask to project the point based on the GeometryServiceSample.

[self.gst projectGeometries:self.geometryArray:outSR];


When building I get the following warning:
'AGSGeometryServiceTask' may not respond to '-projectGeometries::'

which makes the application crash with the following output:
-[AGSGeometryServiceTask projectGeometries::]: unrecognized selector sent to instance 0x727a140
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AGSGeometryServiceTask projectGeometries::]: unrecognized selector sent to instance 0x727a140'

After checking the AGSGeometryServiceTask.h I found that "projectGeometries" is actually missing:
AGSGeometryServiceTask.h

Can you tell what I'm doing wrong?

BR, Paul
0 Kudos
DiveshGoyal
Esri Regular Contributor
You're missing an argument name in the method. It should be -
[self.gst projectGeometries:self.geometryArray toSpatialReference:outSR];
0 Kudos
PaulJereb
Emerging Contributor
thanks a lot! the projectGeometries call seems to work now (the simulator connects to sampleserver3) but after that the following methods are not called.

- (void)geometryServiceTask:(AGSGeometryServiceTask *)geometryServiceTask operation:(NSOperation *)op didReturnProjectedGeometries:(NSArray *)projectedGeometries
{
 NSLog(@"didReturnProjectedGeometries");
}

- (void)geometryServiceTask:(AGSGeometryServiceTask *)geometryServiceTask operation:(NSOperation*)op didFailProjectWithError:(NSError *)error {
 NSLog(@"didFailProjectWithError");
}


Is there again something I forgot? I used the GeometryServiceSample as a basis and triple checked already if something's missing...

BR, Paul
0 Kudos
KOLDODUARTE
Emerging 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 all & thanks all to, especially Harikant Jammi,

With your solutions, now It works fine, good job Jammi!

BR,
Koldo.
0 Kudos
HarikantJammi
Emerging Contributor
welcome koldo!!

glad to know that my code helped you.

Regards,
Harikant Jammi
0 Kudos