ThinkGeo.com    |     Documentation    |     Premium Support

Image Rotation

Hi,


is any opportunity to rotate my Image due to the side of moving? I know the angle, but method Rotate() doesn't work.


I use EditInteractiveOverlay and ScalingImageStyle for my Image.


And the second question is how can I do not show the part of the text using the instruments above? For example, I determine the meaning of the column ["Type"] as "BMW"+"  530i"+"  Black". I want to disappear "Black". If I remove "Black" from ...["Type"]="BMW"+"  530i" there is now image after double clicking on the map. I use project "DraggingIcon Advanced" to be more clear. 


Thank you,


Nick.



I am afraid we don’t understand very well your request. Can you reexplain? And of course, it always helps to have the post including a sample app to illustrate your issue. Thank you.

Thank you, Val, for your respond.


 This is my time_tick to move Image. I'd like to turn Image to the side of moving. If I insert the string pointShape.Rotate(angle), it doesn't work. If I insert the string  ((ScalingImageStyle)(valueStyle.ValueItems[valueStyle.ValueItems.Count - 1].CustomStyles[0])).RotationAngle = angle, it doesn't work. 


Thank you,


Nick


 



 private void timer_Tick(object sender, EventArgs e)
            
        {
            string text = DateTime.Now.Ticks.ToString();
            PointShape pointShape = new PointShape();
            double angle = 0;

            foreach (Feature feature in winformsMap1.EditOverlay.EditShapesLayer.InternalFeatures)
            {
                ValueStyle valueStyle = (ValueStyle)winformsMap1.EditOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles[0];
                //we loop thru the different ValueItem to get the appropriate icon according to the "Type".
                GeoImage geoImage = null;
                text = feature.ColumnValues["Type"].Trim();
                foreach (ValueItem valueItem in valueStyle.ValueItems)
                {
                    if (text == valueItem.Value)
                    {
                        ((ScalingImageStyle)(valueStyle.ValueItems[valueStyle.ValueItems.Count - 1].CustomStyles[0])).RotationAngle = 45;
                        geoImage = ((ScalingImageStyle)(valueStyle.ValueItems[valueStyle.ValueItems.Count - 1].CustomStyles[0])).Image;
                        break;
                    }
                }
                pointShape = feature.GetShape() as PointShape;
            }

            LineShape shipLine = winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count - 1].GetShape() as LineShape;
            if (index < shipLine.Vertices.Count)
            {
                Vertex newPosition = shipLine.Vertices[index];
                Vertex nextPosition = new Vertex();
                try
                {
                    nextPosition = shipLine.Vertices[index + 1];
                }
                catch
                {
                    nextPosition = shipLine.Vertices[index];
                }
                angle = GetAngleFromTwoVertices(newPosition, nextPosition);
                //pointShape.Rotate(pointShape, angle);
                pointShape.X = newPosition.X;
                pointShape.Y = newPosition.Y;
                pointShape.Id = text;
                
                winformsMap1.EditOverlay.EditShapesLayer.Open();
                winformsMap1.EditOverlay.CanDrag = true;
                winformsMap1.EditOverlay.CalculateAllControlPoints();
                winformsMap1.EditOverlay.EditShapesLayer.EditTools.BeginTransaction();
                
                winformsMap1.EditOverlay.EditShapesLayer.EditTools.Update(pointShape);
                winformsMap1.EditOverlay.EditShapesLayer.EditTools.CommitTransaction();
                winformsMap1.EditOverlay.EditShapesLayer.Close();
                winformsMap1.Refresh(winformsMap1.EditOverlay);
                
            }
            else
            {
                index = 0;
            }
        }


I have a clearer idea of what is going on but it is still difficult to estimate where the problem is if we don’t have a sample app we can run. Can you take the code you send me and have it in a self contained sample app. I think it would take you less time to put that together than for us trying to create a new project and trying to recreate your conditions only with the sample code you sent us. Thank you for your understanding.

Hi, Val,


excuse me, it took me too much time and , say the truth, I couldn't make executable sample. If you don't mind, I show you my code in logical way.


 


 



 private void Form1_Load(object sender, EventArgs e)
    {
      SqlDataAdapter shipAdapter = new SqlDataAdapter("select Ico,1,2,3 from CPoint order by 1", myConnection);
            DataSet shipSet = new DataSet("CPoint");
            shipAdapter.Fill(shipSet, "CPoint");
            EditInterActiveIcon(shipSet);
    }
        
        private void EditInterActiveIcon(DataSet iconSet)
        {
            // настройка EditInteractiveOverlay
            //EditInteractiveOverlay used because it already has the logic for dragging.
            EditInteractiveOverlay editInteractiveOverlay = new EditInteractiveOverlay();

            //Sets the property IsActive for DragControlPointsLayer to false so that the control point (as four arrows) is not visible.
            editInteractiveOverlay.DragControlPointsLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.IsActive = false;
            editInteractiveOverlay.DragControlPointsLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            //Sets the property IsActive for all the Styles of EditShapesLayer because we are using a ValueStyle instead.
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.IsActive = false;
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle.IsActive = false;
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.IsActive = false;

            //ValueStyle used for displaying the feature according to the value of the column "Type" for displaying with a flag or unknown icon.
            ValueStyle valueStyle = new ValueStyle();
            valueStyle.ColumnName = "Type";
            //valueStyle.ColumnName = "Base";
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
            int i = 0;
            foreach (DataRow drShip in iconSet.Tables[0].Rows)
            {
                MemoryStream ms = new MemoryStream((byte[])drShip[0]);
                ScalingImageStyle scalingImageStyle = new ScalingImageStyle(GeographyUnit.DecimalDegree, new GeoImage(ms), 100000000, 1000000, 50, 10);
                Collection[Style] iconPointStyle = new Collection[Style]();
                iconPointStyle.Add(scalingImageStyle);
                valueStyle.ValueItems.Add(new ValueItem(Convert.ToString(drShip[1]) + " " + Convert.ToString(drShip[2]), iconPointStyle));
                i = i + 1;
            }
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            editInteractiveOverlay.EditShapesLayer.Open();
            editInteractiveOverlay.EditShapesLayer.Columns.Add(new FeatureSourceColumn("Type"));
            editInteractiveOverlay.EditShapesLayer.Columns.Add(new FeatureSourceColumn("Base"));
            ScalingTextStyle scalingTextStyle = new ScalingTextStyle(GeographyUnit.DecimalDegree, "[Type]", 100000000, 1000000, 12, 6);
            scalingTextStyle.OverlappingRule = LabelOverlappingRule.NoOverlapping;
            scalingTextStyle.DuplicateRule = LabelDuplicateRule.OneDuplicateLabelPerQuadrant;
            scalingTextStyle.YOffsetInPixel = 30;
            ScalingTextStyle scalingTextStyle1 = new ScalingTextStyle(GeographyUnit.DecimalDegree, "[Base]", 100000000, 1000000, 12, 6);
            scalingTextStyle1.OverlappingRule = LabelOverlappingRule.NoOverlapping;
            scalingTextStyle1.DuplicateRule = LabelDuplicateRule.OneDuplicateLabelPerQuadrant;
            scalingTextStyle1.YOffsetInPixel = 45;
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(scalingTextStyle);
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(scalingTextStyle1);
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            
            editInteractiveOverlay.EditShapesLayer.Close();

            Collection<Feature> iconFeature = new Collection<Feature>();
            i = 0;
            foreach (DataRow drShip in iconSet.Tables[0].Rows)
            {
                iconFeature.Add(new Feature(new PointShape()));
                iconFeature[i].ColumnValues["Type"] = Convert.ToString(drShip[1]) + " " + Convert.ToString(drShip[2]);//; // +" " +
                iconFeature[i].ColumnValues["Base"] = Convert.ToString(drShip[3]);
                editInteractiveOverlay.EditShapesLayer.InternalFeatures.Add(Convert.ToString(drShip[1]) + " " + Convert.ToString(drShip[2]), iconFeature[i]);// + " " +
                i = i + 1;
            }
            //Sets the properties of EditInteractiveOverlay to have the appropriate behavior.
            editInteractiveOverlay.CanAddVertex = false;
            editInteractiveOverlay.CanDrag = true;
            editInteractiveOverlay.CanRemoveVertex = false;
            editInteractiveOverlay.CanResize = false;
            editInteractiveOverlay.CanRotate = false;
            editInteractiveOverlay.CalculateAllControlPoints();
            winformsMap1.EditOverlay = editInteractiveOverlay;
            winformsMap1.Refresh(winformsMap1.EditOverlay);
            //disable the double click modes in order to not have second effect behavior 
            //of the map when adding or removing an icon by double clicking
            winformsMap1.ExtentOverlay.DoubleLeftClickMode = MapDoubleLeftClickMode.Disabled;
            winformsMap1.ExtentOverlay.DoubleRightClickMode = MapDoubleRightClickMode.Disabled;
            //iconSet.Clear();
        }

 private void routToolStripMenuItem_Click(object sender, EventArgs e)
// menu Item to determine the rout of moving
        {
            It = "Root";
            dockingWindow1.Text = this.Text + ": " + It;
            tripFlag = true;
            CustomTrackInteractiveOverlayLine customTrackInteractiveOverlay = new CustomTrackInteractiveOverlayLine();
            customTrackInteractiveOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.ContestedBorder1;
            customTrackInteractiveOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            winformsMap1.TrackOverlay = customTrackInteractiveOverlay;
            winformsMap1.Refresh(winformsMap1.TrackOverlay);

  // datagridview1 - grid to show the points of moving           
            dataGridView1.Visible = true;
            dataGridView1.Width = dockingWindow5.Width;
            dataGridView1.Height = dataGridView1.ColumnHeadersHeight;
            dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dataGridView1.Location = new Point(5, 30);
            comboBox1.Location = new Point(5, 5); // type vehicle
            comboBox2.Location = new Point(comboBox1.Location.X + 130, 5); //number vehicle
            comboBox3.Location = new Point(comboBox2.Location.X + 130, 5); //vehicle holder
            button1.Location = new Point(dockingWindow5.Width - 300, 5);   // to make model of moving
            button2.Location = new Point(dockingWindow5.Width - 200, 5);   // clear the results of modeling
                        
            treeView1.Nodes.Add("Rout");
            treeView1.Nodes[treeView1.Nodes.Count - 1].Checked = true;

            
            foreach (ToolStripButton tlsbt in toolStrip1.Items)
            {
                tlsbt.CheckState = CheckState.Unchecked;
            }
            //btnTrackNormal.CheckState = CheckState.Checked;
            btnTrackLine.CheckState = CheckState.Checked;
        }

 private void winformsMap1_MapClick(object sender, MapClickWinformsMapEventArgs e)
            // making rout points
        {
            
                if (e.MouseButton == MapMouseButton.Left)
                {
                        double angle = 0;
                        double currentDist = 0;
                        string To =  "00:00:00";
                        pointLineShape.Vertices.Add(new Vertex(e.WorldX, e.WorldY));
                        DistanceLineShape.Add(pointLineShape);
                        proj4Projection.Open();
                        Vertex geoVertex = proj4Projection.ConvertToExternalProjection(pointLineShape.Vertices[pointLineShape.Vertices.Count - 1].X, pointLineShape.Vertices[pointLineShape.Vertices.Count - 1].Y);
                        if (pointLineShape.Vertices.Count >= 2)
                        {
                            angle = GetAngleFromTwoVertices((Vertex)pointLineShape.Vertices[pointLineShape.Vertices.Count - 2], (Vertex)pointLineShape.Vertices[pointLineShape.Vertices.Count - 1]);
                            PointShape pointShape1 = new PointShape(pointLineShape.Vertices[pointLineShape.Vertices.Count - 2]);
                            PointShape pointShape2 = new PointShape(pointLineShape.Vertices[pointLineShape.Vertices.Count - 1]);
                            // Определение дистанции между точками (0.658 - коэффициент, уменьшающий погрешность и представляющий расстояние в милях) 
                            currentDist = Math.Round((pointShape1.GetDistanceTo(pointShape2, GeographyUnit.Meter, DistanceUnit.Meter)* 0.658), 2) ;
                            To = Convert.ToString(Convert.ToDateTime(CurrentDate) - Convert.ToDateTime(dataGridView1.Rows[0].Cells[6].Value));
                        }
                        proj4Projection.Close();
                       
                        dataGridView1.Rows.Add(1);
                        
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[0].Value = Convert.ToString(dataGridView1.Rows.Count);
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[1].Value =  Convert.ToString(e.WorldX);
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[2].Value =  Convert.ToString(e.WorldY);
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[3].Value = DecimalDegrees.d_To_DMs(geoVertex.Y, 2, DecimalDegrees.Type.Latitude);// Convert.ToString(e.WorldX);
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[4].Value = DecimalDegrees.d_To_DMs(geoVertex.X, 2, DecimalDegrees.Type.Longitude);
                        dataGridView1.Rows[dataGridView4.Rows.Count - 1].Cells[5].Value = To.ToString();
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[6].Value = statusBarPanelTimeReader.Text;
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[7].Value = Math.Round(angle,0);
                        dataGridView1.Rows[dataGridView1.Rows.Count - 1].Cells[8].Value = Math.Round(currentDist*1000/3600,2);
                        dataGridView1.Height = dataGridView1.Rows[0].Height * (dataGridView1.Rows.Count + 1);
                        dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
                        if (dataGridView1.Rows.Count >= 11)
                        {
                            dataGridView1.Height = dataGridView1.Rows[0].Height * 11;
                        }
                    }
                }
        }

 private void button1_Click(object sender, EventArgs e)
        // making model of moving
        {
            if (comboBox1.Text == "" || comboBox2.Text == "" || comboBox3.Text == "" || dataGridView1.Rows.Count == 0)
            {
                MessageBox.Show("Smth wrong");
                return;
            }
            LineShape shipLine = winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[winformsMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count - 1].GetShape() as LineShape;
            if (dataGridView1.Rows.Count != shipLine.Vertices.Count-1)
            {
                MessageBox.Show("Smth wrong");
                return;
            }
            timer5.Interval = 1000;
            timer5.Start();
        }

        int index = 0;
        private void timer5_Tick(object sender, EventArgs e)
        // timer of moving
        {
            if (index <= dataGridView1.Rows.Count - 1)
            {
                winformsMap1.EditOverlay.EditShapesLayer.Open();
                winformsMap1.EditOverlay.EditShapesLayer.InternalFeatures.Remove(comboBox1.Text + " " + comboBox2.Text + " " + comboBox3.Text);
                PointShape planeShape = new PointShape(Convert.ToDouble(dataGridView1.Rows[index].Cells[1].Value), Convert.ToDouble(dataGridView1.Rows[index].Cells[2].Value));

                Feature carFeature = new Feature(planeShape);
                {
                    carFeature.ColumnValues["Type"] = comboBox1.Text + " " + comboBox2.Text;
                    carFeature.ColumnValues["Base"] = comboBox3.Text;
                    winformsMap1.EditOverlay.EditShapesLayer.InternalFeatures.Add(comboBox1.Text + " " + comboBox2.Text + " " + comboBox3.Text, carFeature);
                    winformsMap1.EditOverlay.CanDrag = true;
                    winformsMap1.EditOverlay.CalculateAllControlPoints();
                    winformsMap1.Refresh(winformsMap1.EditOverlay);
                    index = index + 1;
                }
            }
            else
            {
                index = 0;
            }
        }

 private double GetAngleFromTwoVertices(Vertex fromVertex, Vertex toVertex)
            
        {
            double alpha;

            // Avoid divide by zero run values.
            if ((int)toVertex.Y - (int)fromVertex.Y == 0)
            {
                if ((int)toVertex.X > (int)fromVertex.X)
                    alpha = 90;
                else
                    alpha = 270;
            }
            else
            {
                // Calculate angle from offset.
                double riseoverrun = (double)((int)toVertex.X - (int)fromVertex.X) / (double)((int)toVertex.Y - (int)fromVertex.Y);
                double radians = Math.Atan(riseoverrun);
                alpha = radians * ((double)180 / Math.PI);

                // Handle quadrant specific transformations.       
                if (((int)toVertex.X - (int)fromVertex.X) > 0 && ((int)toVertex.Y - (int)fromVertex.Y) < 0) //
                    alpha += 180;
                if (((int)toVertex.X - (int)fromVertex.X) < 0 && ((int)toVertex.Y - (int)fromVertex.Y) < 0) // 
                    alpha += 180;
                if (alpha < 0)                                                                              // 
                    alpha += 360;
                if (alpha == 0 && (int)toVertex.Y - (int)fromVertex.Y < 0)
                    alpha = 180;
            }
            return alpha;
        }

So in this code I try to make the model of moving vehicle, which is in EditInteractiveOverlay & which has custom style - ScalingImageStyle. Everything is OK, my image moves, but it do not turn to the angle of moving.



((ScalingImageStyle)(valueStyle.ValueItems[valueStyle.ValueItems.Count - 1].CustomStyles[0])).RotationAngle = 45;


doesn't work.

Thank you for your help,


Nick


 



Nick, thanks for your post and sample code. This is Yale, hope I can help you.


First, I tested the Rotate API in pointShape, and it works fine, following is the code snippet:



PointShape pointShape = new PointShape(10, 10);
pointShape.Rotate(new PointShape(0, 0), 45);

string wkt = pointShape.GetWellKnownText();
// Result is correct.  POINT(8.65927457071936E-16 14.142135623731)

Second, I think what we are trying to do is to rotate the Image set in the ScalingImageStyle , right? And if I am not making any mistake, the customized style ScalingImageStyle is from our following code gallery. Right?

code.thinkgeo.com/projects/show/16


Any more questions please feel free to let me know.


Thanks.


Yale

 



Yale, thanks a lot. I’ll try your recommendation and give a replay. 
  
 I’ve got one more question, more principle that above one. I make new post.  
  
 Thank you for your help, 
  
 Nick 


Nick, 
  
 Thanks for your feedback and let me know any result from it. I appreciate your kindly understanding on posts. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale