ThinkGeo.com    |     Documentation    |     Premium Support

Popup Overlay

 Hello,


 
I need to open a balloon  (popupoverlay) in a “virtual” earth location.  Please see an image for a balloon location.
I tried using  ToScreenCoordinate function: wpfMap.ToScreenCoordinate(feature.GetBoundingBox().GetCenterPoint()), but it gives me a wrong results.
 
I have one ShapeFileFeatureLayer for a world and one InMemoryFeatureLayer for the points.
 

 
Please help.
 
Thanks,
Inna
 

Inna,


 I would like to clarify the Wrap property is meant to give the map a little more flexibility when panning past the 180 degree meridien so that you can still see geographic features east or west of that reference meridien. But you need to do all your logic on the main central map. Never lose sight of the central map and you should be fine. Also I do not recommend zooming out so far out seeing the world several times, you are not gaining anything cartographically and it makes it more confusing for you to keep track of the central map. Thank you.



Val, 
  
 I am not zooming out too far,  it was just an example to clarify what I need.  But when I am panning past 180 degrees, it will be really nice to have that flexibility. 
 I will appreciate if you can give me a direction or maybe sample code how to achieve this. 
  
 Thanks a lot, 
 Inna

Inna,


 I checked the situation of PopupOverlay with WrapDateline mode. It is currently not supported. I will meet with the Development team to see how soon this is going to be added. In the meantime, I suggest you stay on the central map to do PopupOverlay. Thank you.



What? I show Popups with WrapDataline in either virtual and real worlds normally. You just need to specify the coordinates beyond 180º 
  
 Carlos

Carlos,


  Well, you are getting more familiar than me on that WrapDateline thing. Can you share us some code or even better a sample? Samples always help everybody at both the ThinkGeo community and at ThinkGeo, itself. Thank you.



Carlos, 
  
 I will appreciate all your help. 
  
 My features are pointing always to the real world and I am having troubles to calculate virtual earth coordinates (where I want to display a popup). 
 Maybe you can point me to the right direction. 
  
 Thanks, 
 Inna

Inna,


  Did you look at the Wrap Dateline Mode sample in the Code Community wiki.thinkgeo.com/wiki/Map_Suite_Wp...eline_Mode?


 Before we get  some sample from Carlos, I want to point you out to this sample and its WrapDatelineProjection. I want to make sure that you understand how the different coordinate systems relate to each other. For example, if you go pass the 180 meridien west and have -200, it really means 160 east. I want to make sure that you grasp that concept. Thank you.


 



Hi Inma, 



What Val pointed out is really the key. Please find how simple is it (you can do it more elegantly by using projections as in the Code Community Example), but just for easy reading: 



[Code]

Imports ThinkGeo.MapSuite.Core
Imports ThinkGeo.MapSuite.WpfDesktopEdition

Class Window1

  Private Sub WpfMap1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles WpfMap1.Loaded

    WpfMap1.MapUnit = GeographyUnit.DecimalDegree
    WpfMap1.CurrentExtent = New RectangleShape(-50, 16, 66, -50)

    WpfMap1.BackgroundOverlay.BackgroundBrush = New GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255))

    Dim worldLayer As ShapeFileFeatureLayer = New ShapeFileFeatureLayer(System.Windows.Forms.Application.StartupPath & "\Data\Countries02.shp")
    worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1
    worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

    Dim layerOverlay As LayerOverlay = New LayerOverlay()
    layerOverlay.WrappingMode = WrappingMode.WrapDateline
    layerOverlay.Layers.Add("worldLayer", worldLayer)

    WpfMap1.Overlays.Add("WorldOverlay", layerOverlay)

    Dim PopupOv As New PopupOverlay()
    WpfMap1.Overlays.Add("PopupOverlay", PopupOv)

    'Show a popup on "Real" world
    Dim PopupLocation As New Point(-3, 40)
    Dim RealWorldPopup As Popup = New Popup(PopupLocation)
    RealWorldPopup.Content = "Real"
    PopupOv.Popups.Add(RealWorldPopup)

    'Show a popup on "Left virtual" world
    PopupLocation.X -= 360
    Dim LeftVirtualWorldPopup As Popup = New Popup(PopupLocation)
    LeftVirtualWorldPopup.Content = "Left Virtual"
    PopupOv.Popups.Add(LeftVirtualWorldPopup)

    'Show a popup on "Right virtual" world
    PopupLocation.X += 2 * 360
    Dim RightVirtualWorldPopup As Popup = New Popup(PopupLocation)
    RightVirtualWorldPopup.Content = "Right Virtual"
    PopupOv.Popups.Add(RightVirtualWorldPopup)

    WpfMap1.Refresh()
  End Sub

End Class
[/Code]
 

 




Carlos,


 Thank you so much. I took your code, converted it to C# and it worked! Below is the C# version for C# programmers. Also, I included some comments and explicitly created some variables to be more descriptive.


Inna, I hope this has clarified this issue.


 



   wpfMap1.MapUnit = GeographyUnit.DecimalDegree;
    wpfMap1.CurrentExtent = new RectangleShape(-50, 16, 66, -50);

    wpfMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255));

    ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"C:\ThinkGeo\Support\MapData\Countries02.shp");
    worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1;
    worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

    LayerOverlay layerOverlay = new LayerOverlay();
    layerOverlay.WrappingMode = WrappingMode.WrapDateline;
    layerOverlay.Layers.Add("worldLayer", worldLayer);

    wpfMap1.Overlays.Add("WorldOverlay", layerOverlay);

    PopupOverlay PopupOv = new PopupOverlay();
    wpfMap1.Overlays.Add("PopupOverlay", PopupOv);

    //Show a popup on "Real" world
    double Longitude = -3;
    double LongitudeSpan = 360;  //From 180 west to 180 east
    Point PopupLocation = new Point(Longitude, 40);
    Popup RealWorldPopup = new Popup(PopupLocation);
    RealWorldPopup.Content = "Real";
    PopupOv.Popups.Add(RealWorldPopup);

    //Show a popup on "West virtual" world

    PopupLocation.X = -LongitudeSpan + Longitude; //Longitude span is negative because we go the west
    Popup LeftVirtualWorldPopup = new Popup(PopupLocation);
    LeftVirtualWorldPopup.Content = "Left Virtual";
    PopupOv.Popups.Add(LeftVirtualWorldPopup);

    //Show a popup on "East virtual" world
          
    PopupLocation.X = LongitudeSpan + Longitude;  //Longitude span is positive because we go to the east
    Popup RightVirtualWorldPopup = new Popup(PopupLocation);
    RightVirtualWorldPopup.Content = "Right Virtual";
    PopupOv.Popups.Add(RightVirtualWorldPopup);

    wpfMap1.Refresh();


Carlos, Val – Thank you for your help.

I think this solution only works with map in degrees. My map is in meters and I am having trouble to convert  360 degree offset  to meters.



Hi Inma, 
  
 It should be the same, when you init the map at the beginning and define the map extent, you know how much meters does it have of longitude width, don’t you? 
  
 Carlos

Inna,


 yes, in theory the principle is the same. Below is the code adapted for map in meters using Spherical Mercator projection (Google Map, Bing Map, Open Street Map). It roughly works but there is a slight offset and it needs to be investigated. Thank you.


 



wpfMap1.MapUnit = GeographyUnit.Meter;
wpfMap1.CurrentExtent = new RectangleShape(-10000000, 5000000, 10000000, -5000000);

wpfMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255));

ManagedProj4Projection proj4 = new ManagedProj4Projection();
proj4.InternalProjectionParametersString = ManagedProj4Projection.GetWgs84ParametersString();
proj4.ExternalProjectionParametersString = ManagedProj4Projection.GetSphericalMercatorParametersString();

ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"C:\ThinkGeo\Support\MapData\Countries02.shp");
worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
worldLayer.FeatureSource.Projection = proj4;

LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.WrappingMode = WrappingMode.WrapDateline;
layerOverlay.Layers.Add("worldLayer", worldLayer);

wpfMap1.Overlays.Add("WorldOverlay", layerOverlay);

PopupOverlay PopupOv = new PopupOverlay();
wpfMap1.Overlays.Add("PopupOverlay", PopupOv);

//Show a popup on "Real" world
double Easting = -410184;
worldLayer.Open();

double SphericalMercatorSpan = worldLayer.GetBoundingBox().Width;  
proj4.Close();
worldLayer.Close();
Point PopupLocation = new Point(Easting, 4971042);
Popup RealWorldPopup = new Popup(PopupLocation);
RealWorldPopup.Content = "Real";
PopupOv.Popups.Add(RealWorldPopup);

//Show a popup on "West virtual" world

PopupLocation.X = -SphericalMercatorSpan + Easting; //Longitude span is negative because we go the west
Popup LeftVirtualWorldPopup = new Popup(PopupLocation);
LeftVirtualWorldPopup.Content = "Left Virtual";
PopupOv.Popups.Add(LeftVirtualWorldPopup);

//Show a popup on "East virtual" world

PopupLocation.X = SphericalMercatorSpan + Easting;  //Longitude span is positive because we go to the east
Popup RightVirtualWorldPopup = new Popup(PopupLocation);
RightVirtualWorldPopup.Content = "Right Virtual";
PopupOv.Popups.Add(RightVirtualWorldPopup);

wpfMap1.Refresh();
 

 



 



OK. Good. Because I did exactly what you suggested and got the offset when zooming in. 
 I thought I am doing something wrong, that’s why I decided to post this question. 
  
 Can you please investigate this issue. 
  
 Thanks, 
 Inna

Inna,


 Yes, I will present this issue to the Development team at the next meeting I have with them. I will let you know what they think. Thank you.



Hello Inna, Carlos, 
  
 We did deep research and we think we can’t support for now.  
  
 Because the Popup is inherited from the System.Windows.Controls.ContentControl, in other words, one popup is a separated wpf Control, we are unable to get all of its status in a simple way. we tried the Object.MemberWiseClone method, but still unable to get the full information of a Popup. 
  
 Sorry for the inconvenience. 
  
 Regards, 
  
 Gary

But the issue only appears with MapUnit=Meters, right?

Gary,


Maybe I don’t understand you, but I don’t want to duplicate popup control. I just want to create a new popup control in a different position (on a virtual world). 

When I calculated new position (similar to what Val suggested), I got a slight offset when zooming in. Code does work, minus an offset. Therefore, I am thinking  it is a bug in your system, and not a new feature.


Carlos – I never tested it with decimal degrees. Do you also have a slight offset when zooming in?


Inna



Hello Inna,


Sorry I misunderstanding you want the Popup’s WrapDateLine, now I think you just wants to create two new Popops at the virtual location.  The reason is that the default extent of WrappingDateLine is incorrect for some scales, The width of the scale’s corresponding extent is unable to be dived with no remainder. We will try some updates here later. Now, please try the updated sample code in the attached.


Regards,


Gary



DisplayASimpleMap.xaml.cs.zip (1.34 KB)

Gary, 
  
 It does work. Thank you. 
  
 Inna