ThinkGeo.com    |     Documentation    |     Premium Support

Problem Projecting Shapes

Hi,


I am working on an application that automatically changes the coordinate system of map layers when zoomed in beyond a certain threshold scale.  I noticed that after setting the Projection on certain map layers I would get an error when trying to call GetBounidngBox on the feature layer.  Specifically, this happens if I set the Projection object on a layer that's in geographical NAD83 to projected NAD83 zone 16.


So then I tried saving the extent of the layer as a Rectangle shape and then converting the rectangle to whaterver coordinate system I need and got essentially the same error.  As a test, I took the coordinates of the Lower Right corner of the saved Rectangle and tried to convert just that one coordinate pair and I still get essentially the same error, stack trace below:


System.InvalidOperationException was unhandled

  Message=latitude or longitude exceeded limits

  Source=MapSuiteCore

  StackTrace:

       at ThinkGeo.MapSuite.Core.ManagedProj4Projection.ThrowException(Int32 errorNumber)

       at ThinkGeo.MapSuite.Core.ManagedProj4Projection.ConvertToExternalProjectionCore(Double[] x, Double[] y)

       at ThinkGeo.MapSuite.Core.Projection.ConvertToExternalProjection(Double x, Double y)

       at TestProjection.Module1.Main() in C:\Users\steller\AppData\Local\Temporary Projects\TestProjection\Module1.vb:line 7

       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)

       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)

       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)

       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

       at System.Threading.ThreadHelper.ThreadStart()

  InnerException:


 


Here is a code snippet:



Dim oProj4 As New ManagedProj4Projection(ManagedProj4Projection.GetEpsgParameters(4269), ManagedProj4Projection.GetEpsgParameters(26916))
oProj4.Open()
Dim oVertex As Vertex = oProj4.ConvertToExternalProjection(-178.215026855469, 18.9247817993164)

 


Any ideas?  


Steve



I can jump in on this one.     -178 degrees is almost on the international date line, way out in the pacific.   A UTM projection is on "valid" relative to distortion within a six degree range, and mathematically valid within maybe a 12 to 24 degree range.   Zone 16 is around -84 degrees… its center is a little east of Chicago.    So the error being thrown is because you are trying to use a projection that is not applicable to the data being projected.

Hi Ted, 
  
 Thanks for your response.   
  
 Yes, I kind of figured the reason for the error was that the coordinate being transformed produced a coordinate that falls outside of the UTM zone to which it’s being converted.  Which brings me to another question. 
  
 I can apply the UTM zone 16 coordinate system to my NAD83 geographic layer and it works just fine.  My understanding is that the same ManagedProj4Projection object that is managing the drawing of the NAD83 geographic layer is also converting coordinates.  These same coordinates must surely exist in the geographic layer.  So why does the same error NOT occur when reprojecting this layer? 
  
 Thanks, 
  
 Steve

Steven, 
  
 Can you rephrase your question? I am not sure I understand what your concern is. If you are wondering why the same error does not occur when going from UTM to Geographic, it is because UTM values are always going to correspond to valid Geographic values while the reverse is not always true as Ted explained it. Thank you.

Val, 



Thanks for your response.  Sorry to ask my question in a confusing way. 



These are the steps: 



1. Apply UTM Zone 16 coordinate system to a layer in UTM83 geographic.  The layer is for US counties. 

3. Attempt to get the extent of the layer by calling GetBoundingBox. 

3. Every time I try to do this the GetBoundingBox returns an error: 



System.ArgumentOutOfRangeException was unhandled 

Message=The input double value is out of range. 

Parameter name: maxX 

Source=MapSuiteCore 

ParamName=maxX 

StackTrace: 

at ThinkGeo.MapSuite.Core.x6d719af406ea4c2c.x12e7df23649722cf(Double x86d4512e4c7d8814, String x34decc57f0820440, Double xaee3bf422e2fd725, x1acec04cd58c1af5 xa798986acdb65a29, Double xe21f77686f8b957e, x1acec04cd58c1af5 x495f4164830ffad5) 

at ThinkGeo.MapSuite.Core.x6d719af406ea4c2c.xb86d8097d383be05(Double x86d4512e4c7d8814, String x34decc57f0820440, Double xaee3bf422e2fd725, x1acec04cd58c1af5 xa798986acdb65a29) 

at ThinkGeo.MapSuite.Core.RectangleShape..ctor(Double minX, Double maxY, Double maxX, Double minY) 

at ThinkGeo.MapSuite.Core.MultipointShape.GetBoundingBoxFromPoints(IEnumerable`1 points) 

at ThinkGeo.MapSuite.Core.MultipointShape.GetBoundingBoxCore() 

at ThinkGeo.MapSuite.Core.BaseShape.GetBoundingBox() 

at ThinkGeo.MapSuite.Core.Projection.ConvertToExternalProjection(RectangleShape rectangleShape) 

at ThinkGeo.MapSuite.Core.FeatureSource.ConvertToExternalProjection(RectangleShape rectangle) 

at ThinkGeo.MapSuite.Core.FeatureSource.GetBoundingBox() 

at ThinkGeo.MapSuite.Core.FeatureLayer.GetBoundingBoxCore() 

at ThinkGeo.MapSuite.Core.Layer.GetBoundingBox() 

InnerException:  


I can send a sample app but it's too big to attach.


Thanks,


Steve


 



It is normal that you are going to get an error if you project all the counties of the US to UTM Zone 16. As Ted explained, a UTM zone is valid within a certain longitude range. As you can see in the attached picture of the UTM zones for the USA. You can apply the UTM zone 16 to counties that are only in some states such as Illinois, Indiana, Kentucky Tennessee and a few more.



 


If you want more in depth explanation on this, I suggest you check out this site: en.wikipedia.org/wiki/Universal_Tra...ate_system



Thanks Val, 
  
 I am well-versed in coordinates systems and have spent a number of years programming applications using ESRI products such as MapObjects and ArcEnigne.  What I am attempting is to reproduce an application I wrote in the last couple of years that allows the user to see a geographical coordinate system when zoomed out past a certain threshold, but to have the features displayed in a projected zone when zoomed in (for example, for editing).  I had very little trouble making this work in ESRI’s ArcEngine but it appears I will have to use a workaround to make it work with ThinkGeo. 
  
 Just an observation.  There is no reason why you should not be able to get an Extent with GetBoundingBox on a geographical layer that’s been projected into a zoned coordinate system, except for the validation that’s being performed behind the scenes.  It would be nice if there was an option to disable the validation. 
  
 Thanks for your help, 
  
 Steve

I'm a customer.. not a ThinkGeo person, but I'll defend ThinkGeo here.    In my opinion, based upon my experience with ESRI products, there is no way you could have displayed data at 178 degrees west in a NAD83 UTM Zone 16 projection.   And if your data is US counties, how do you even get that point :).


We do the same thing as you... we display a geographic projection when zoomed out beyond a state or two, and based upon where the user zooms into, we switch to UTM NA83 projections.  But we calculate the projection based upon the centroid of the view we are zooming to.  That way, we are always displaying the data in its least distorted projection.    For this purpose, ThinkGeo's tools work just fine, w/o a work around.


There must be something that we are overlooking on how you are getting the geographic coordinates of the bounding box.



Hi Ted,


No need to come to ThinkGeo's defense, I'm a big fan of their products, ESRI not so much.


The western tip of the Aleutian Islands in Alaska is around -178 degrees and, as you can see it is diplaying while being projected in NAD83 Zone 16.  It is not a useful view, nor is it my intention to ever use it in this way.  



Here's my real problem.  I have implemented a TOC (table of contents) control that displays the layers in the map.  One of the things you can do is right-click on a layer and choose 'Zoom To Layer'.  Let's say this is done on the counties layer when the map is zoomed in on some features that are projected to UTM Zone 16.  The only reason I need the 'GetBoundingBox' function would be to get a full extent for the counties layer.  My intention was to get the extent, project it into the UTM83 Geogaphic coordinate system and then apply that exten to the map.  The Projection object for each of the layers would also need to be adjusted.  I probably just need to change the order of things a bit, apply the UTM83 Geographic coordinate system first and do the 'GetBoundingBox' second.


I'll get it figured out eventually, especially with all the help to be found on this forum.


Thanks again,


Steve


 


 


 


 



Ahhhh…   I got to wondering about Alaska after I posted.    We don’t have to deal with that problem in our app. 
  
 Thanks for the info!

Hi, Guys, 
  
 I read through all the posts and found I am far lost on the projection knowledge, some of them are still not very clear to me. Hmm, thanks for all your post and contributions, I really learnt a lot from it. 
  
 Thanks. 
  
 Yale 


Steven, 
  
   Do you still need help on that projection topic? If you still do, let us know and we will work on the complete solution for you. Also, if you have it figured out, it would be great to share it with the community. I think it could also be a good idea for a Code Community project. Thank you.

Hi Val, 
  
 I think I have solved my problem.  I rearranged the order that things happen in the code and now, when I need to get the full extent for a layer in a geographic coordinate system I remove any projection that’s been applied first, then GetBouningBox returns a valid result without an error.  It appears that your Services Edition sample, ‘Geodetic To State Plane’ does something similar to what we are doing in our application.  We are using a layer of UTM zones to determine what zone we’re in so we know which projected coordinate system to apply when the map is zoomed in.  We do the same thing for State Plane zones. 
  
 Thanks, 
  
 Steve

Steven, 
  
 Thanks for your sharing of ideas, I appreciate it very much. We have some very profound samples shown in our code gallery; it would be great if a sample showing how your problem be solved to be added to the gallery, while just feel easy if not convenient.  
  
 Any more questions please feel free to let me know. 
  
 Thanks. 
  
 Yale 


Yale, 
  
 I will consider putting something together that demonstrates the concept of changing to an appropriate UTM Zone when zoomed in beyond a certain scale, say 1:316,800 (this is simply a constant defined in our code).  It may be awhile before I am able to do this so please be patient. 
  
 Thanks for the great forum! 
  
 Steve

Steven, 
  
    Yes, that would be great if you could send us something related to that. In the meantime, I will try to find some time to create a project similar to yours for the Code Community. Thank you again for the idea.