ThinkGeo.com    |     Documentation    |     Premium Support

Rotate all layers

Hi, 


I need to rotate my map to display the direction in which the vehicle(train) is heading to the top of the map.  I can rotate one layer on the winformsmap by using RotationProjection.Angle but I need to rotate all the layers on the map. At the moment it only rotates the last layer which  i loaded from it's shapefile. I display railway lines, stations, signals and the moving train in different layers.


I also need to display a North Arrow.


The code that I got in UseRotationProjectionForAFeatureLayer only displays one layer and the code in the MapRotationDemo is for an old version of Map Suite. I am using VS2005 and DesktopEditionFull3.0.184 Beta 2, will upgrade to 199 soon.


Regards, Alta


 


 



Alta, 
  
 I went through the same thing.  Here’s what I did.  (This is a test I did under Beta 1 a month or so ago…currently I’m waiting to get my trial period for Beta 2 extended, so I can only look at the code, not run it.) 
  
 In the form’s definition define a RotationProjection variable: 
      RotationProjection rotationProjection; 
 I’m loading the map layout from an XML file, so when I start this I create the RotationProjection: 
      rotationProjection = new RotationProjection(); 
 Then each time I’m about to load a layer into the map, I did this: 
      layer.FeatureSource.Projection = rotationProjection; 
 Once everything is loaded, I then set the map’s current extent: 
      winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(new RectangleShape(UpperLeft, LowerRight)); 
      winformsMap1.Refresh(); 
 (I have the extent hardcoded but you could pull it out of one of the layers.) 
 And finally when I want to rotate the map: 
      rotationProjection.Angle += 5; 
      winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(winformsMap1.CurrentExtent); 
      winformsMap1.Refresh(); 
  
 That’s it.  When I get my Beta 2 running again I could compile the pieces into a simple program and post some real code if needed. 
  
 Allen 
  
  


Allen, 
  
   Thanks for helping on that!  Let me know if you have any problem in getting your evaluation extended. 
  
 David

Thanks for the help Allen, but it still rotates only one layer. 



I open a shapefile and display the stations in a StaticOverlay, then I display the railway line from another shapefile in a StaticOverlay. The train's position is displayed in a DynamicOverlay. 

Should I not display everything in one Overlay? I haven't figured out how to do that.


And another problem: when I do  MapClick, the e.WorldX and e.WorldY are totally different from the initial coordinates e.g. a station that was in 29.9  -26.5 is now in 31.5  -26.8



Alta… 
  
 If nobody else responds and I can get my eval extended I’ll simplify my test program and post the code.  If we can get everything in the StaticOverlay rotating, it’s a step in the right direction.  I don’t know how the rotation works with layers in both the static and dynamic overlays.  I haven’t tried that, but I’m willing to give it a shot.  There have been discussions here over the pros and cons of using both overlays, and unless you need to refresh just certain layers I don’t think you gain anything by using both.  Obviously if you’re rotating you need to refresh everything, so putting just the train into the dyamic overlay is probably not needed.  If the map was not being rotated it would, of course, be a different situation.  Without the actual data, I’m not going to speculate on the coordinates issue. 
  
 David… 
  
 I was in touch with the salesrep and was expecting a call from him on Friday but I was in and out of the office a bit, so perhaps I missed his call. If there’s anything you can do without stepping on his toes, I’m in.  I think he said he had to get a tech support person logged into my PC, so he might not mind someone else dealing with this. 
  
 Allen

Allen, 
  
   Sorry for the phone tag with the sales rep.  The person who can help you would be Ryan.  You can also call the general sales line and take to any of the sales people.  We have a little utility but there is some back and forth and it is usually fastest if you can do it all at one time with Ryan.  As far as I know the sales reps will be in today.  As soon as they show up I will contact them and see which one has your account and let them know that we need to expedite this and that you have been very helpful in the forums etc…   
  
   Every time I hear you saying things like “I could help you better if I could get my evaluation extended” it makes me feel so sorry for you and I wish there was something I could do!  I am going to push with all the leverage I have to get this resolved today! 
  
 David

Thanks Allen, I  put everything in StaticOverlay but I use InMemoryFeatureLayer for the train where i create a feature from a  pointshape and then add it: layer.InternalFeatures.Add("Train", feature) and then winformsMap1.StaticOverlay.Layers.Add("", layer). 
 I will try to create that layer as a StaticOverlay 


Alta,


My evaluation has been extended, so I'm back in action.  I haven't seen anything new from you, so hopefully this will still be of interest.  I've extracted code from a more complicated test program to display just two layers and rotate them 5 degrees every 1 second.  Both layers are in StaticOverlay, but let's see if we can get that working.  The two layers are a highway and hydro.  Both layers indeed rotate together.  I know you had more issues, but again, one step at a time.



private void Form1_Load(object sender, EventArgs e)
{
    ShapeFileFeatureLayer layer1 = new ShapeFileFeatureLayer(@"C:\_ThinkGeo Shapefiles\disp_rd_hwy.shp");
    layer1.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Highway3;
    layer1.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
    layer1.FeatureSource.Projection = rotationProjection;

    ShapeFileFeatureLayer layer2 = new ShapeFileFeatureLayer(@"C:\_ThinkGeo Shapefiles\hydro_polygons.shp");
    layer2.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Water1;
    layer2.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
    layer2.FeatureSource.Projection = rotationProjection;

    layer1.Open();
    RectangleShape r = layer1.GetBoundingBox();
    PointShape UpperLeft = r.UpperLeftPoint;
    PointShape LowerRight = r.LowerRightPoint;
    layer1.Close();

    winformsMap1.MapUnit = GeographyUnit.Meter;
    winformsMap1.StaticOverlay.Layers.Add(layer1);
    winformsMap1.StaticOverlay.Layers.Add(layer2);
    winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(new RectangleShape(UpperLeft, LowerRight));
    winformsMap1.Refresh();
}

private void timer1_Tick(object sender, EventArgs e)
{
    rotationProjection.Angle += 5;
    winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(winformsMap1.CurrentExtent);
    winformsMap1.Refresh();
}

Hopefully this will help,


Allen



Ugh...that didn't come through right.  Not sure why. Here's the same code in an attachment.


 



415-Form1.cs (2.12 KB)

Allen,  
  
 I modified your messages a bit and now the codes display fine.  Thanks for sharing :) 
  
 Ben.

Ben, 
  
 Thanks for tidying that code.  I added the code tag inside my message and then copied and pasted right from Visual Studio.  Since I put “csharp” in the code tag I expected the code to have line breaks after the semicolons but it didn’t.  Is this normal?  Is there a better way to paste C# code? I randomly checked other messages and didn’t see any real long C# code in any.  I started a second posting and began to explicitly press Enter after each line, but that got tedious pretty soon and I went the attachment route. 
  
 Allen


 Allen, 
  
 The editor is supposed to handle the codes well if it is in a “csharp” tag block, you do not need to press Enter after each line yourself. I saw some other clients have the same problem but I never met that. Usually, if I want to post some message without attachment or pictures; I will just paste it in the “Quick Reply” and add the “csharp” tag to wrap the code. If I have to use the other way to post, I will make sure all the other part is posted properly first and then I click the “Source” button and paste the code. As there will be many HTML tags in “Source Mode” and sometimes it’s difficult to find the right place to paste the code, usually I replace the code with some markers like many “0” first when I was in “View” mode and then when I switch to “Source”, I can easily find the right place to paste. 
  
 Hope that helps! 
  
 Ben 


Hi Allen and Ben 
 Thanks for the code! It works, but I ran into the following problems: 
  
 1) I do not open all the ShapeFileFeatureLayers one after the other as you did in Form1_Load.  My code is on a button click, where I prompt the user to choose which layer (from a shapefile)  he want to open.  After one layer is opened, the user can click again and open another layer. But on the opening of the second layer, I get the error:  
 System.InvalidOperationException was unhandled 
   Message="The projection is not open.  Please open it before calling this method." 
  
 If I do: 
      rotationProjection = New RotationProjection() 
      layer.FeatureSource.Projection = rotationProjection 
      winformsMap1.StaticOverlay.Layers.Add( 
  
 Only one layer rotate. Can you please help met with a solution for this? 
  
 2) I display a train (as a lineShape) on the railway line (which is one of the layers)  in an InMemoryFeatureLayer and add it to the StaticOverlay. Every time I get the new GPS coordinates of the train, I must display the train again on the right place on the map. I get about 10 coordinates because the length of the trains varies and I must display the whole train with relation to the railway line. 
  
 The problem here is that the InMemoryFeatureLayer does not rotate with the other layers and does not stay "on top" of them. Any ideas how to solve this? 
  
 3) The last "nice to have" will be an arrow to indicate North. I saw some code for edition 2 but could not convert it. 
  
 Thanks, I would really appreciate your help. 
 Regards 
 Alta

Alta, 
  
 I understand the difference in #1…let me see if I can get the rotation to work that way.  We’ll try to tackle them one at a time, OK? 
  
 Allen


 Alta, 
  
 Here you go…this program continually rotates the map and lets you add layers one at a time via an OpenFileDialog.  In fact, you can see the map rotating in the background as the program waits with the dialog box open for you to add another layer. 
  
 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


using ThinkGeo.MapSuite.DesktopEdition;
using ThinkGeo.MapSuite.Core;

namespace SimpleRotate
{
    public partial class Form1 : Form
    {
        RotationProjection rotationProjection = new RotationProjection();
        RectangleShape baseExtent = new RectangleShape();
        int LayerNumber = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            winformsMap1.MapUnit = GeographyUnit.Meter;
            openFileDialog1.Filter = “Shapefiles | *.shp”;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            rotationProjection.Angle += 5;
            winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(winformsMap1.CurrentExtent);
            winformsMap1.Refresh();
        }

        private void btnAddLayer_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ShapeFileFeatureLayer NewShapeFile = new ShapeFileFeatureLayer(openFileDialog1.FileName);
                LayerNumber++;
                // Don’t know what type of feature, so set both
                NewShapeFile.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Highway5;
                NewShapeFile.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
                NewShapeFile.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
                NewShapeFile.FeatureSource.Projection = rotationProjection;
                winformsMap1.StaticOverlay.Layers.Add(“Layer” + LayerNumber.ToString(), NewShapeFile);

                try
                {
                    if (winformsMap1.StaticOverlay.Layers.Count > 0)
                    {
                        ShapeFileFeatureLayer tempLayer = (ShapeFileFeatureLayer)winformsMap1.StaticOverlay.Layers[“Layer1”];
                        tempLayer.Open();
                        winformsMap1.CurrentExtent = rotationProjection.GetUpdatedExtent(tempLayer.GetBoundingBox());
                        tempLayer.Close();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                winformsMap1.Refresh();
            }
        }
    }
}



Alta…I think you can ignore "baseExtent"…that is leftover junk from an earlier attempt. 
  
 Ben…yeah, pasting it into Quick Reply worked perfectly.  I will stick to that when inserting code. 
  
 Allen

Thanks Allen! 
 My mistake was that I had a layer.Open after I declared the layer.  It must be after Layers.Add

Allen,  
  
 Thanks for sharing, and thanks for your nice codes. :) 
  
 Ben

More good news on my problem #2. I can rotate the InMemoryFeatureLayer with the ShapeFileFeatureLayer. My RotationProjection was not kept up to date.  
 Now it is time to take on #3 - to display a North arrow. 
 Thanks for your help! 
 Alta

Alta,


Here is a small demo showing how to add your North Arrow and rotate it. You can see the first time you click “Rotate”, the map will be a bit misplaced. That’s a bug and we will fix it in the next version.


Thanks,


Ben



451-NorthArrowDemo.zip (104 KB)