# How to convert the meters to degrees in GCS_WGS_1984?

7917
6
02-15-2013 11:30 AM
Highlighted
by
Occasional Contributor II
Hi Everybody:

I am writing ArcObjects tool that works on the data with WGS84 spatial reference, where the X/Y coordinates are degrees. I want to use ArcObjects to buffer a point with 1 meter distance. If I use the ITopologicalOperator.Buffer, it will buffer the point with a number in the unit of degrees. I don't know how to get this number now. Do you have any idea?

Here is what I know at this moment:
* if I the point's spatial reference is an IGeographicCoordinateSystem but now a IProjectedCoordinateSystem
* the IGeographicCoordinateSystem.CoordinateUnit.ConversionFactor and IGeographicCoordinateSystem.CoordinateUnit.RadiansPerUnit are both 0.017453, which is roughly PI/180, which is not telling how many meters each degree is
* I am using ArcObjects 10.0

Any idea? Thank you!
Tags (5)
1 Solution

Accepted Solutions
Highlighted
by
Occasional Contributor II
I just wrote some code for that, the basic idea is to convert the geometry to a projected coordinate system, buffer it, and then covert it back to the GCS.

`IGeometry projectedShape = (originalShape as IClone).Clone() as IGeometry; ISpatialReferenceFactory3 srFactory = new SpatialReferenceEnvironmentClass(); IProjectedCoordinateSystem pcs = srFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_Sphere_Sinusoidal); pcs.SetFalseOriginAndUnits(0, 0, 1000000); projectedShape.Project(pcs); IGeometry5 buf = (projectedShape as ITopologicalOperator).Buffer(bufferMeters) as IGeometry5; buf.Project5(originalShape.SpatialReference, 0);`

Any other idea?
6 Replies
Highlighted
by Esri Notable Contributor
You might try IBufferConstruction / IBufferConstructionProperties instead. It supports geodesic-based buffers on points at 10.0.
Highlighted
by
Occasional Contributor II
Hi mkennedy:

I tried the following code but it still give me a huge buffer instead of a 1-meter buffer. How to make it work?
Thank you!

`IBufferConstruction bufConstructor = new BufferConstructionClass();(bufConstructor as IBufferConstructionProperties).Unit = new LinearUnitClass();object unitName = "Meter";object unitAlias = "Meter";object unitAbbreviation = "M";object unitRemarks = "Meter is the linear unit";object unitMetersPerUnit = 1;((bufConstructor as IBufferConstructionProperties).Unit as ILinearUnitEdit).Define(ref unitName,      ref unitAlias, ref unitAbbreviation, ref unitRemarks, ref unitMetersPerUnit);IGeometry buf = bufConstructor.Buffer(m_input_segment_polyline.FromPoint, 1)// draw the buffer`

You might try IBufferConstruction / IBufferConstructionProperties instead. It supports geodesic-based buffers on points at 10.0.
Highlighted
Regular Contributor III
The developer help states that the IBufferConstruction.Buffer method does not use the properties exposed in IBufferConstructionProperties.  Try using one of the other buffer methods and see if that works.
Highlighted
by
Occasional Contributor II
Hi Neil:

Thank you for pointing out this. I tried the following code, but still doesn't work, what shall I do?
Thank you!

`IBufferConstruction bufConstructor = new BufferConstructionClass();(bufConstructor as IBufferConstructionProperties).Unit = new LinearUnitClass();object unitName = "Meter";object unitAlias = "Meter";object unitAbbreviation = "M";object unitRemarks = "Meter is the linear unit";object unitMetersPerUnit = 1;((bufConstructor as IBufferConstructionProperties).Unit as ILinearUnitEdit).Define(ref unitName, ref unitAlias, ref unitAbbreviation, ref unitRemarks, ref unitMetersPerUnit);IEnumGeometry input = new GeometryBagClass();IGeometryCollection output = new GeometryBagClass();(input as IGeometryCollection).AddGeometry(m_input_segment_polyline.FromPoint);IDoubleArray distances = new DoubleArrayClass();distances.Add(1);bufConstructor.ConstructBuffers(input, 1, output);\\ bufConstructor.ConstructBuffersByDistances2(input, distances, output); \\alternativeIElement ele = GeoUtils.AddGraphicToMap((m_application.Document as IMxDocument).FocusMap, output.Geometry, new RgbColorClass() { Red = 255, Green = 0, Blue = 0 }, new RgbColorClass { Red = 0, Green = 0, Blue = 255 }, 3);`

The developer help states that the IBufferConstruction.Buffer method does not use the properties exposed in IBufferConstructionProperties.  Try using one of the other buffer methods and see if that works.
Highlighted
Regular Contributor II
You can't convert meters to degrees.  Degrees are an angular unit and do not have a constant length.  Degrees of Latitude are roughly constant, the distance between the north pole and the equator along the greenwich meridian is approx. 10 000 000 meters /90 degrees.  A degree of longitude varies from approx 44 000 000/360 at the equator to 0 at the poles.  If you want to buffer one meter around a point that is defined in geographic units, I suggest you project the point into a projected coordinate system defined in meters (hopefully one that minimizes distortion for that part of the globe) and buffer one meter and reproject the output back to geographic if need be.

I think the geodesic based buffers are basically the same idea.  Looks like the units you set are not correct.  Geographic are angular units yet it looks like you are using a linear unit with a meter to unit ratio as one (so basically redefining meters.)

You can specify the buffer distance in a distance unit different than that of the spatial reference of the input geometries. The unit must be of the same type (angular or linear) as that of the input geometries' spatial reference.

I am not sure how you then define the buffer distance as a linear unit if the spatial reference of the input point is an angular unit.
Highlighted
by
Occasional Contributor II
I just wrote some code for that, the basic idea is to convert the geometry to a projected coordinate system, buffer it, and then covert it back to the GCS.

`IGeometry projectedShape = (originalShape as IClone).Clone() as IGeometry; ISpatialReferenceFactory3 srFactory = new SpatialReferenceEnvironmentClass(); IProjectedCoordinateSystem pcs = srFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_Sphere_Sinusoidal); pcs.SetFalseOriginAndUnits(0, 0, 1000000); projectedShape.Project(pcs); IGeometry5 buf = (projectedShape as ITopologicalOperator).Buffer(bufferMeters) as IGeometry5; buf.Project5(originalShape.SpatialReference, 0);`

Any other idea? 