ThinkGeo.com    |     Documentation    |     Premium Support

Another strange map rotation incident

Good morning...


I know already that nobody's every seen this before, but I am having a map rotation issue that is driving me crazy.  Depending on how I code my map rotation the contents of an InMemoryLayer gets out of sync with the contents of a SqlServer layer.  How can this happen? 


Here's what my map starts as (I am driving across one marking lot to a driveway and then across another parking lot)...



...and as soon as I rotate the map the layers get out of sync...



Depending on how I code the rotation and CenterAt() call, this loss of layer sync happens after the first or second redraw.


In case it helps, this is what I'm trying to do: In this mode, the vehicle's direction of travel always points to the top of the map.  To prevent a lot of map refreshing, when the vehicle's bearing has changed by a certain amount, I recenter the map at the most latest vehicle position and also rotate the map so that the vehicle's position is pointing at the top of the map again.  But I have constantly struggled to get this to happen while the map is rotated.  I can set the rotation to 0, apply my changes, then rotate the map, but in order to get that to work I have to refresh the map after setting the rotation to 0, which causes a double redraw that nobody likes.


I am still struggling with recentering the map and applying rotation in one step.  If I do it one way, I get goofy stuff like you see above.  If I do it another way, the map jumps all over the place.  PLEASE!  Do not direct me to the samples...I have been there many times before and the multi-layer complications I am seeing with this application, which has 30 or 40 layers, don't show up when you're just rotating one layer.  AND, as I've said before, the example DOES NOT attempt to rotate the map and recenter it at the same time. 


Thanks for any suggestions!


Allen



I am seeing the same problem, although I am doing both a move and a rotate at the same time.  The InMemoryFeatureLayers get out of sync.  If the direction of travel is North then everything sync’s back up.

 


Hi Allen & Robert,


Currently we can't re-produce the issue you mentioned. But we provide a sample project to demonstrate how to rotate and center map at the same time. Please check the attachement "RotateAndCenterMap" for more information (You can get the shape file "Countries02.shp" from folder "HowDoISamples\SampleData\Data" along with DesktopEdition).


Please let us know if you have further questions.


Regards,


Ivan


 



RotateAndCenterMap.zip (11.9 KB)

I’m trying to figure out what the CustomRotationProjection is trying to do with the pivotVertex property.  What shape do I use for that?  Just grab any shape and use the first line? (will this work with PolygonShape?) Or do I need to process every shape in the InMemoryLayer every time I move/rotate? I have 6 InMemoryFeatureLayers that have potentially 100’s of shapes in each layer, will this be a performance hit? 


I'm trying to figure out what the CustomRotationProjection is trying to do with the pivotVertex property. What shape do I use for that? Just grab any shape and use the first line? (will this work with PolygonShape?) Or do I need to process every shape in the InMemoryLayer every time I move/rotate? I have 6 InMemoryFeatureLayers that have potentially 100's of shapes in each layer, will this be a performance hit? 

 


BTW, your sample file doesn't compile.  It's missing files in the Properties folder.



Allen,


 Looking at your screen shots, it seems to me that you are not setting the CustomRotationProjection to all the FeatureLayers of your map. Remember that you have to set the rotation projection to ALL the FeatureLayers on the map, otherwise you are going to have some unexpected behavior. The first thing I would do is to make sure of that. I think that you can run the code below which assign the CustomRotationProjection to all your FeatureLayers. Once we know that all the FeatureLayers have the rotation projection set, then the rotating and centering of the map should work as expected as you can see in this Code Community samples:


Centering and Rotating wiki.thinkgeo.com/wiki/Map_Suite_De...d_Rotating


 If you are still seeing unexpected behavior, please send us a little self contained sample from you. Thank you.


 


 


 



foreach (Overlay overlay in winformsMap1.Overlays)
{
    if (overlay is LayerOverlay)
    {
        LayerOverlay layerOverlay = (LayerOverlay)overlay;
        foreach (Layer layer in layerOverlay.Layers)
        {
            if (layer is FeatureLayer)
            {
                FeatureLayer featureLayer = (FeatureLayer)layer;
                featureLayer.FeatureSource.Projection = customRotationProjection;
            }
        }
    }
}


Robert, 
  
 I verified that the sample provided by Ivan can be compiled successfully, while if you want to run it, you probably need to copy the data (Countries02.shp etc 5 files) into the data folder. If you still cannot compile it, could you verify which version of Desktop Edition are you using against? 
  
 Any more questions please feel free to let me know. 
  
 Thanks. 
  
 Yale 


Val, 
  
 I will blame this one on the programmer…me.  I was doing essentially what you show in your code, but I had two chunks of code…one for the SQL Server layers and one for the InMemoryLayers (plus a “fall through” for the MapShapeLayers that did nothing)…it hadn’t occured to me at the time I wrote the code that SQL Server layers and InMemoryLayers are both derived from FeatureLayer and I could access the FeatureShape.Projection property with a single chunk of code.  ANYHOW, in the one chunk I had the order of setting the RotationProjection’s angle at a different sequence.  For some reason the previous testing of this code did not reveal this error.  I will confess: when I screw up, it’s usually a dumb one. 
  
 I continue to believe rotation in MapSuite is too low-level for the typical programmer and there should be a way of hiding a lot of these details unless they are needed.  When I have a few minutes I intend to submit this to the enhancement suggestion site.  What I would like to do is to tell the map to rotate to a certain angle…PERIOD…and any interactions I do with the map, such as clicking, adding, querying or removing features, etc., are done via unrotated coordinates.  In our application users sometimes add new features on the map, which can be rotated at the time, and I have to explicitly derotate the feature to add a record to the database.  I don’t believe I should have to deal with stuff at this level unless I need to.  Or they click on the map and I need to query the database with that position, but it needs to be derotated because the data in the database isn’t rotated, of course.  To me, this adds code that I don’t think needs to be there. 
  
 Allen 


Allen, 
  
   I am glad I could point you out thru my code to the problem in your code that would cause the unexpected rotation behavior. But you have nothing to blame yourself about, I have to confess that the way we have our API for doing map rotation is too low level as you explain with clarity in the second paragraph of your last post.  
   I believe we have the API like that for map rotation is because Map Suite cannot accomplish rotation for the full map when Raster layers (Geotiff, Mr SID etc) are involved. Currently, the map rotation can be done only with vector layers and it would be misleading to have a simple API for map rotation when this is still limited for only some types of layers. 
  I know that the development team has in plan to have map rotation working with raster layers also which would make it fully functional. We will then present to the developer an easy API at the map level for this. 
  Thank you for reminding us of this current limitation of Map Suite.

Allen,


 And make sure that this issue is in the Enhancement Tracker  so that it gets high priority for the development team to work on :-)


helpdesk.thinkgeo.com/EnhancementTracker



I hate repeating myself, but I could really use answers to the following: 
  
 I’m trying to figure out what the CustomRotationProjection is trying to do with the pivotVertex property. What shape do I use for that? Just grab any shape and use the first line? (will this work with PolygonShape?) Or do I need to process every shape in the InMemoryLayer every time I move/rotate? I have 6 InMemoryFeatureLayers that have potentially 100’s of shapes in each layer, will this be a performance hit?  
  
 Thanx, 
 Rob

Robert,


 Sorry I forgot your post after answering to Allen's question.


I supposed that you are referring to the property PivotVertex of the class CustomRotationProjection in the Code Community sample Custom Rotation Projection wiki.thinkgeo.com/wiki/Map_Suite_De...Projection


 You have to be aware that this class CustomRotationProjection is used for the specific case where you have a shape that you want to rotate while the map in general stays unrotated as you can see in the example of the sample. This scenario might arise when you get a shape from an external source such as a CAD and it is not in the same angle as the map and you want o apply some rotation specifically to that layer to match the map. We apply rotation to it based on the pivot being the center of the shape but the pivot could be at any other location based on your needs. I stress that this operation has nothing to do with wanting to rotate the map as a whole, Map Rotation.


 If you want to apply Map Rotation to your entire map which the case similar to Allen, you need a different class, RotationProjection which does not have a PivotVertex property. You can look at the Code Community sample Centering and Rotating wiki.thinkgeo.com/wiki/Map_Suite_De...d_Rotating to see how to use this class.


  From reading your posts, I am assuming that what you want is to do Map Rotation like Allen. In this case, DO NOT use CustomRotationProjection class that you find in Custom Rotation Projection sample. This is for a different purpose.


 I hope I cleared out some confusion that might have occured.



Well if that is the case, then the original problem stands.  I have all layers projection property set to the same rotationProjection, yet, as the I drive around and the map rotates, the InMemoryLayers get out of sync with the Shape Layers.

Robert,


 From what you are describing, it leads me to believe that the InMemoryFeatureLayers that get out of sync do not have their Projection property set to RotationProjection. This is basically the same case as Allen's.


 I recommend that you run the code I posted for Allen that makes sure all the layers have the RotationProjection set correctly. You can find it in the Post of 04-11-2011 11:51 AM of this thread.


 If the problem persists, we will need a small self contained sample app from you to investigate the problem. Thank you.



Val, Robert, etc. 
  
 I was a bit confused by the purpose of the CustomRotationProjection myself.  When I need to rotate or unrotate a feature, I’m calling the ConvertToInternalProjection or ConvertToExternalProjection methods of one of the ProjectionRotations assigned to a layer, as I was advised to do some time before.  I’m guessing its purpose is to demonstrate some more advanced techniques.   
  
 Robert…are you using InMemoryFeatureLayers or MapShapeLayers?  I really like MapShapeLayers because we had some layers with complex styling that was difficult to do with a ValueStyle and initially had a lot of them in our application, but I have dropped almost all use of them because they don’t rotate; I had to call methods to rotate the shapes and reload the layer in code whenever the map rotates.  More convoluted code to rotate a map!  I am also curious if you’re using a SINGLE RotationProjection object and assigning it to all of your layers.  If you look back in the forum you’ll find this has the potential for trouble if you start to use the RotationProjection methods since internally it opens and closes things…I was getting errors and the ultimate solution is to have a unique RotationProjection for each layer.  Val’s snipped above doesn’t show it, but in my code once I have all of the layers loaded I am creating a NEW rotationProjection for EACH LAYER, and then setting RotationProjection.Angle while iterating through all of the layers, much like what Val’s snippet shows, although I’m not using the CustomRotationProjection. 
  
 I am very pleased to see someone at ThinkGeo finally admit that the way programmers have to implement this stuff is tedious.  Val has urged me to add this to the enhancement tracker, and after all this frustration I certainly will.  I recently submitted an item to the enhancement tracker to beef up MapShapeLayers so that they have a FeatureSource and can be rotated along with the rest of the map.  I have been exchanging some e-mails with Ryan over the MapShapeLayer enhancement and mentioned to him that we were using a competitor’s map component and rotation is just as low-level.  If ThinkGeo could make this more programmer friendly it would be a leg up on the “other” component.  My proposal to him (and this will be what I submit to the enhancement tracker) is that the programmer should just tell the map the angle of rotation, and any coordinate positions I tell the map are in unrotated coordinates and the map code can rotate whatever it needs.  Likewise, if I click on a rotated map and it returns to me the map click point or a feature in unrotated coordinates.  The map knows it is rotated and should be dealing with all of this stuff.  Of course I can understand the reasoning for doing this, as Val explained.  Our application’s map has the potential to be constantly rotated (and it sounds like Robert might be in a similar situation) so I NEVER have data in rotated coordinates because, obviously, those coordinates would constantly be changing.   I just want to be clear that these two issues, the ability to rotate MapShapeLayers, and an overall simplification of rotation, are TWO SEPARATE ISSUES, but if MapShapeLayers could be rotated I would expect that enhancement would be included in an overall simplification of rotation of all the layer types that currently do rotate. 
  
 Whew, I’m all rotated out and will find something else to work on today! 
  
 Allen 
  


Allen, 
  
 Thanks for your post and question. 
  
 About the requirement to get rotation supported in the MapShapeLayer, I am curious which one you are referring to in the following 2 cases: 
 1.Rotate Point Feature locations, in this way, we probably need to set a pivot point.  
 2.Rotate the images attached to the point features while keeping the point feature locations fixed. 
  
 Any more questions please feel free to let me know. 
  
 Thanks. 
  
 Yale 


Hi Yale… 
  
 Other layers, such as MsSql2008FeatureLayer or InMemoryFeatureLayer have a FeatureSource, have a Projection property to which I can attach a RotationProjection, and simply (more or less based on the theme of this posting) rotate the layer simply by changing the RotationProjection.Angle and refresh the map.  A MapShapeLayer HAS NO FEATURE SOURCE and thus there is no easy way to rotate the shapes in the layer; I ended up calling a RotationProjection’s ConvertTo…Projection for each map shape and reloading the layer each time the map’s rotation is changed.  
  
 But don’t take my word for it, it’s in the MapSuite documentation!  Take a look at this wiki page documentation for MapShapeLayer… 
  
 wiki.thinkgeo.com/wiki/ThinkGeo.MapSuite.Core 
  
 where SOMEONE at ThinkGeo once said this: 
  
 “Ideally I would want to make this inherit from the FeatureLayer so you could do spatial queries. In the interests of time I inherited from the Layer to make things simple and show the point of how easy it is to extend Map Suite. When we roll this into the main product we may create a FeatureSource and FeatureLayer.” 
  
 This is what MapShapeLayer must be able to do to have any real value.  If a FeatureSource is added, I can rotate a MapShapeLayer. 
  
 Allen

Hi, Allen, 
  
 Thanks for your post and questions.  
  
 I think we did have some discussions and augments about MapShapeLayer inheritance; we did want to get it implemented by inheriting from the Feature layer instead of the layer, while we changed our ideas at last moment to make it simpler to use and make it easier to understand.  
  
 I think you have got the right direction to get Projection supported, if we want to enhance it, we definitely will go it in this way too, that is adding a Projection property, and  project all the point features at the beginning of DrawCore. What do you think? 
  
 Any more questions please feel free to let me know. 
  
 Thanks. 
  
 Yale 


Ok, my problem was caused by the programmer - me - as well.  I was assigning the projection to all the FeatureLayers, but was not assigning it to the InMemoryLayers.  The only remaining problem with rotation I have left is the MarkeOverlay doesn’t seem to take a projection.  I will probably fix that by changing to an InMemoryLayer. 
  
 Now if InMemoryLayers would only support an animated GIF…  :-) 


Ok, my problem was caused by the programmer - me - as well.  I was assigning the projection to all the FeatureLayers, but was not assigning it to the InMemoryLayers.  The only remaining problem with rotation I have left is the MarkeOverlay doesn’t seem to take a projection.  I will probably fix that by changing to an InMemoryLayer. 
  
 Now if InMemoryLayers would only support an animated GIF…  :-)