ThinkGeo.com    |     Documentation    |     Premium Support

EditInteractiveOverlay&DragInteractiveOverlay

Hi,


Please help. I tried number of projects in the Code Community  that deals with setting Styles for EditInteractiveOverlay & DragInteractiveOverlay to drag my Icons. If I add 2 icons at same time (winform1.Load) as in DraggingIcon or DraggingPointStyle, everything is ok - I can capture any icon and move it where I want. But I don't know the number and the type of Icons beforehand. Every mouseclick on winform1 I must to add new Icon and in this case  I can move only the last added icon.


Here is the attachment where I demonstrate my problem.


Thankks a lot.


 


 



private_void_DataGridViewClickIcon.doc (29.5 KB)

Nick, 
  
 Thanks for your post and question. 
  
 I am sorry to say that I am not 100%  sure about the problem you are talking about, if I am not misunderstanding anything, what you are trying to achieve is to edit some feature previously added instead of the last added one. Right? I think we can achieve this if we can query out it. 
  
 It would be nice if you could provide me a sample to show the problem, which would be very helpful to identify the problem. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale  


Yale, thank you for the answer. In the attachment I try to show my problem.



private void MapClickIcon(sender object, MapClickWinformsMapEventArgs e)
            
        {
                winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
                winformsMap1.CurrentExtent = new RectangleShape(-97.7591, 30.3126, -97.7317, 30.2964);
                winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255));


                //EditInteractiveOverlay used because it already have 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 bus or car icon.
                ValueStyle valueStyle = new ValueStyle();
                valueStyle.ColumnName = "Type";
                // Run procedure counter 
                if (integer == 0)
                {
                    PointStyle carPointStyle = new PointStyle(new GeoImage(@"F:\car_normal.png"));
                    carPointStyle.PointType = PointType.Bitmap;
                    valueStyle.ValueItems.Add(new ValueItem("Car", carPointStyle));
                }
                else
                {
                    PointStyle busPointStyle = new PointStyle(new GeoImage(@"F:\bus_normal.png"));
                    busPointStyle.PointType = PointType.Bitmap;
                    valueStyle.ValueItems.Add(new ValueItem("Bus", busPointStyle));
                }
                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.Close();
                if (integer == 0)
                {
                    Feature carFeature = new Feature(new PointShape(-97.7507, 30.3092));
                    carFeature.ColumnValues["Type"] = "Car";
                    editInteractiveOverlay.EditShapesLayer.InternalFeatures.Add("Car", carFeature);
                }
                else
                {
                    Feature busFeature = new Feature(new PointShape(-97.7428, 30.3053));
                    busFeature.ColumnValues["Type"] = "Bus";
                    editInteractiveOverlay.EditShapesLayer.InternalFeatures.Add("Bus", busFeature);
                }
                integer = integer + 1;
                //Sets the properties of EditInteractiveOverlay to have the appropriate behavior.
                //Make sure CanDrag is set to true.
                editInteractiveOverlay.CanAddVertex = false;
                editInteractiveOverlay.CanDrag = true;
                editInteractiveOverlay.CanRemoveVertex = false;
                editInteractiveOverlay.CanResize = false;
                editInteractiveOverlay.CanRotate = false;
                editInteractiveOverlay.CalculateAllControlPoints();

                winformsMap1.EditOverlay = editInteractiveOverlay;
                winformsMap1.Overlays.Add(editInteractiveOverlay);
                winformsMap1.Refresh();
            }

 

This is the simplest sample of drawing two images on the Map. The variable <integer> is the counter of clicking. The first click - car is drawn and we can capture it and drag anywhere, the second click - bus is drawn and we can capture it and drag anywhere, but  can't capture and drag the car already. Do you understand me. Pardon if something wrong, English is not my native language :)

 Thank you.

Yale, thanks again. I found out the solution of my problem in DraggingIconAdvanced project. Best regards, Nick

Nick, 
  
 Thanks for letting me know your status, I am glad seeing you are making progress. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale 


Yale, pardon me, can't understand. Here is the code which works properly: 



 
 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";
            Collection<PointStyle> iconPointStyle = new Collection<PointStyle>();
            int i = 0;
            foreach (DataRow drShip in shipSet.Tables[0].Rows)
            {
                MemoryStream ms = new MemoryStream((byte[])drShip["Ico"]);
                iconPointStyle.Add(new PointStyle(new GeoImage(ms)));
                iconPointStyle[i].PointType = PointType.Bitmap;
                valueStyle.ValueItems.Add(new ValueItem(Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["2"]) + " " +
                    Convert.ToString(drShip["3"]), iconPointStyle[i]));
                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.Close();

            Collection<Feature> iconFeature = new Collection<Feature>();
            i = 0;
            foreach (DataRow drShip in shipSet.Tables[0].Rows)
            {
                iconFeature.Add(new Feature(new PointShape()));
                iconFeature[i].ColumnValues["Type"] = Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["3"]);
                editInteractiveOverlay.EditShapesLayer.InternalFeatures.Add(Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["2"]) + " " +
                        Convert.ToString(drShip["3"]), iconFeature[i]);
                i = i + 1;
            }
            //Sets the properties of EditInteractiveOverlay to have the appropriate behavior.
            //Make sure CanDrag is set to true.
            editInteractiveOverlay.CanAddVertex = false;
            editInteractiveOverlay.CanDrag = true;
            editInteractiveOverlay.CanRemoveVertex = false;
            editInteractiveOverlay.CanResize = false;
            editInteractiveOverlay.CanRotate = false;
            editInteractiveOverlay.CalculateAllControlPoints();

            winformsMap1.EditOverlay = editInteractiveOverlay;

            winformsMap1.Refresh();
 


But when I change PointStyle on ScalingImageStyle 



 
 ValueStyle valueStyle = new ValueStyle();
            valueStyle.ColumnName = "Type";
            Collection<ScalingImageStyle> iconPointStyle = new Collection<ScalingImageStyle>();
            int i = 0;
            foreach (DataRow drShip in shipSet.Tables[0].Rows)
            {
                MemoryStream ms = new MemoryStream((byte[])drShip["Ico"]);
                iconStyle.Add(new ScalingImageStyle(GeographyUnit.DecimalDegree, new GeoImage(ms), 100000000, 1000000, 50, 10));
                valueStyle.ValueItems.Add(new ValueItem(Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["2"]) + " " +
                    Convert.ToString(drShip["3"]), iconPointStyle<i>));
                i = i + 1;
            }
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;



this string: valueStyle.ValueItems.Add(new ValueItem(Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["2"]) + " " + 

Convert.ToString(drShip["3"]), iconStyle)); 

makes the error: the second argument can't convert to AreaStyle. 



So how I must add ScalingImageStyle to EditInteractiveOverlay for scaling and dragging? 



Thank you



Nick,


Thanks for your questions.
 
Just make sure the ScalingImageStyle is the customized style published from the following code gallery:
code.thinkgeo.com/projects/show/scalingimagestyle
 
I noticed that when you replace the code with ScalingImageStyle used, it cannot be compiled as you said, because when you create a ValueItem, you have to passed in a concrete Style (such as AreaStyle, LineStyle, PointStyle, TextStyle) or a collection of Styles. So try to create a Collection of Styles and add it.
 
Following code snippet is a sample using ValueStyle, and each ValueItem contains a ScalingImageStyle, hope it helps.
 

ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer(@"..\..\Data\worldcapitals.shp", ShapeFileReadWriteMode.ReadOnly);
capitalLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
 
 
ScalingImageStyle scalingImageStyle1 = new ScalingImageStyle(GeographyUnit.DecimalDegree, new GeoImage(@"..\..\Data\Icon1.png"), 100000000, 1000000, 50, 10);
ScalingImageStyle scalingImageStyle2 = new ScalingImageStyle(GeographyUnit.DecimalDegree, new GeoImage(@"..\..\Data\Icon2.png"), 100000000, 1000000, 50, 10);
ScalingImageStyle scalingImageStyle3 = new ScalingImageStyle(GeographyUnit.DecimalDegree, new GeoImage(@"..\..\Data\Icon3.png"), 100000000, 1000000, 50, 10);
 
Collection[Style] styles1 = new Collection[Style]();
styles1.Add(scalingImageStyle1);
 
Collection[Style] styles2 = new Collection[Style]();
styles2.Add(scalingImageStyle2);
 
Collection[Style] styles3 = new Collection[Style]();
styles3.Add(scalingImageStyle3);
 
ValueStyle valueStyle = new ValueStyle();
valueStyle.ColumnName = "POP_RANK";
 
 
valueStyle.ValueItems.Add(new ValueItem("1", styles1));
valueStyle.ValueItems.Add(new ValueItem("2", styles2));
valueStyle.ValueItems.Add(new ValueItem("3", styles3));
 
capitalLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);

 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

Yale,  thank you for the right idea. Here is the code which I made with your help, may be somebody has the same problem as me:


 



 EditInteractiveOverlay editInteractiveOverlay = new EditInteractiveOverlay();
   editInteractiveOverlay.DragControlPointsLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.IsActive = false;
            editInteractiveOverlay.DragControlPointsLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.IsActive = false;
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle.IsActive = false;
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.IsActive = false;

            ValueStyle valueStyle = new ValueStyle();
            valueStyle.ColumnName = "Type";
            //valueStyle.ColumnName = "Label";
            editInteractiveOverlay.EditShapesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();    
            int i = 0;
            foreach (DataRow drShip in shipSet.Tables[0].Rows)
            {
                MemoryStream ms = new MemoryStream((byte[])drShip["Ico"]);
                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("Label"));
            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, "[Label]", 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 shipSet.Tables[0].Rows)
            {
                iconFeature.Add(new Feature(new PointShape()));
                iconFeature[i].ColumnValues["Type"] = Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["2"]);
                iconFeature[i].ColumnValues["Label"] = Convert.ToString(drShip["3"]);
                editInteractiveOverlay.EditShapesLayer.InternalFeatures.Add(Convert.ToString(drShip["1"]) + " " + Convert.ToString(drShip["2"]), iconFeature[i]);
                i = i + 1;
            }
            
            editInteractiveOverlay.CanAddVertex = false;
            editInteractiveOverlay.CanDrag = true;
            editInteractiveOverlay.CanRemoveVertex = false;
            editInteractiveOverlay.CanResize = false;
            editInteractiveOverlay.CanRotate = false;
            editInteractiveOverlay.CalculateAllControlPoints();
            
            winformsMap1.EditOverlay = editInteractiveOverlay;
            winformsMap1.Refresh(winformsMap1.EditOverlay);
  But can I ask one more question?


How determine if I click on feature?






 if (e.MouseButton == MapMouseButton.Right)
                {
                    PointShape clickedPointShape = ExtentHelper.ToWorldCoordinate(winformsMap1.CurrentExtent, e.ScreenX, e.ScreenY, winformsMap1.Width, winformsMap1.Height);
                    Collection<Feature> clickedFeatures = winformsMap1.EditOverlay.EditShapesLayer.QueryTools.GetFeaturesNearestTo(clickedPointShape, GeographyUnit.Meter, 1,
                                                                          ReturningColumnsType.AllColumns);
                    //winformsMap1.EditOverlay.EditShapesLayer.Close();

                    if (clickedFeatures.Count > 0)
                    {
                        //Gets the dimension of the icon and checks if the clicked point is inside it.
                        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;
                        string text = clickedFeatures[0].ColumnValues["Type"].Trim();
                        foreach (ValueItem valueItem in valueStyle.ValueItems)
                        {
                            if (text == valueItem.Value)
                            {
                                geoImage = (GeoImage)valueStyle.ValueItems[0].DefaultPointStyle.Image;
                                break;
                            }
                        }
                        //We check to see if we clicked inside the icon itself.
                        ScreenPointF screenPointF = ExtentHelper.ToScreenCoordinate(winformsMap1.CurrentExtent, clickedFeatures[0], winformsMap1.Width, winformsMap1.Height);
                        RectangleF rectangleF = new RectangleF(screenPointF.X - (geoImage.GetWidth() / 2), screenPointF.Y - (geoImage.GetHeight() / 2),
                                                               geoImage.GetWidth(), geoImage.GetHeight());
                        bool IsInside = rectangleF.Contains(new PointF(e.ScreenX, e.ScreenY));

                        //If inside, removes the feature from the EditShapesLayer of the EditOverlay.
                        if (IsInside == true)
                        {

                        }

}


The  line 



geoImage = (GeoImage)valueStyle.ValueItems[0].DefaultPointStyle.Image;

doesn't return geoImage and it is understandable, but I can't find out how do this. How determine Image of CustomStyle?


Thank you.



Nick,


Thanks for your response.
 
I think the problem is we are using the customStyles instead of Default style, so try to change the code to following way to get the GeoImage out, hope it is what we are trying to get.
 

GeoImage geoImage = ((ScalingImageStyle)valueStyle.ValueItems[0].CustomStyles[0]).Image;

 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

Yale, thanks a lot. How I didn’t get it by myself?!

Nick, 
  
 I am sorry to say that I do not quite understand your point; you mean the GeoImage still return Null in your case? It would be nice and convenient if you could you send me a small sample application. 
  
 Thanks. 
  
 Yale 


Yale, excuse my English, didn't want to say anything you didn't understand.At first, I read your post and hurried to thank you. But when I try to follow your recommend, found out that there is no definition "Image"  in 



GeoImage geoImage = (ScalingImageStyle)valueStyle.ValueItems[0].CustomStyles[0]).Image; 



My sample application is above. From SQL I load images to datagridview. The user make a choice of image in datagridview and draw it on the winforms. With the RightButtonMouseClick on the Image I try to show propertyGrid, for example. 



Thank you.



Nick,


Thanks for your post and feedback. I think the Image property should be there is we are using the ScalingImageStyle from the code gallery.



public GeoImage Image
{
     get { return image; }
     set { image = value; }
}

I think you may miss the cast to ScalingImageStyle first before to get the image as below:



GeoImage geoImage =( (ScalingImageStyle)(valueStyle.ValueItems[0].CustomStyles[0])).Image;

Any more questions just feel free to let us know.


Thanks.


Yale

 



Yale, thank you, everything is ok, I was inattentive, :)

Nick, 
  
 Thanks for letting me know your status. 
  
 Any more questions just feel free to let me know. 
  
 Thanks. 
  
 Yale