deep zoom in the pushpin

Sep 4, 2008 at 6:21 PM
Hi

I am new to deep zoom.
There is a requirement, in which we need to show the pushpins in virtual earth (not necessary that deep zoom should be in deep zoom). But in the callout of the pushpins we need to show large number of images with deep zoom necessarily. And the list of images in the call out will come from an xml.
Is this something thats achievable?
So in this case, is it good to have VE in deep zoom or not?

Can you anyone please guide me in doing this.
We need to complete this in 3 weeks. Any guidance will be helpful.

Thanks
Chinkul
Developer
Sep 5, 2008 at 12:06 AM
in the downloaded source code, you will see in the "DeepEarth" project there is a class called "PushPin" in the "Shapes" folder...

if you look in this class you will see that the actual pushpin is a "String" of xaml e.g. it is a "path" element...

and the "CreateElement" method in this class returns a UIElement...

so...

to make my own pushpin that has a "CallOut" I did this...

in the "DeepEarthPrototype" silverlight project I made a new class, this efectively was just a copy of the "PushPin" class mentioned above...
and I called it "MyPin" and it Inherits "DeepEarth.Shape"


then I made a new silverlight UserControl called "MyPushPin", which I added a button and a Rectangle to be the callout for when you hover over the Button

then in the "MyPin" I just updated the "CreateElement" to return a "New MyPushPin" user control

then in the code in the Page.cs to add the my new custom pushpin I

just create a new instance of the "MyPin" class and then add it to the shapelayer list

e.g. "shapeLayer.List.Add(new MyPin)"

in the MyPushPin user control I have a code behind file etc...
so you have the full power od silverlight in that custom pushpin
I just used the "VisualStateManager" to show and hide the callout when someone hovers over the button etc...
but you can do anything in the custom push pin as it is just a Silverlight User control with code behind....




Sep 5, 2008 at 9:54 AM
Edited Sep 5, 2008 at 10:27 AM
dotnetnoobie, could you possibly share some of the code you described above?

I created a copy of the pushpin control, called it truck. I created a new control and called it TruckControl, it has no code in the code behind (the initializecomponent in the contructor had to be commented out as it didnt want to compile)

The xaml of TruckControl looks like this 

<

 

UserControl x:Class="DeepEarth.Shapes.TruckControl"

 

 

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

 

 

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

 

 

Width="52" Height="35">

 

 

 

<Grid x:Name="LayoutRoot" Background="White">

 

 

 

<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Truck" Width="800" Height="600" Clip="F1 M 0,0L 800,0L 800,600L 0,600L 0,0">

 

 

 

<Canvas x:Name="Group" Width="51" Height="34" Canvas.Left="0.5" Canvas.Top="0.5">

 

 

 

<Path x:Name="Path" Width="51" Height="29.3058" Canvas.Left="-1.37091e-006" Canvas.Top="0" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF000000" Data="F1 M 13.3099,0.5L 50.5,0.5L 50.5,28.8058L 0.499999,28.8058L 0.499999,19.7149L 5.35967,16.7921L 13.3099,0.5 Z "/>

 

 

 

<Path x:Name="Path_0" Width="14.0165" Height="15.7813" Canvas.Left="6.06491" Canvas.Top="0.589661" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 13.693,1.08966L 19.5814,1.08966L 19.5126,15.871L 6.56491,15.871L 13.693,1.08966 Z "/>

 

 

 

<Path x:Name="Path_1" Width="11.2273" Height="6.11365" Canvas.Left="3.00416" Canvas.Top="23.6968" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FFFFFFFF" Fill="#FFFFFFFF" Data="F1 M 3.50416,29.3105C 3.50416,26.4863 5.79361,24.1968 8.61779,24.1968C 11.442,24.1968 13.7314,26.4863 13.7314,29.3105"/>

 

 

 

<Path x:Name="Path_2" Width="8.52273" Height="8.52271" Canvas.Left="4.39115" Canvas.Top="25.4323" Stretch="Fill" Fill="#FF000000" Data="F1 M 8.65251,25.4323C 11.006,25.4323 12.9139,27.3401 12.9139,29.6937C 12.9139,32.0472 11.006,33.955 8.65251,33.955C 6.29903,33.955 4.39115,32.0472 4.39115,29.6937C 4.39115,27.3401 6.29903,25.4323 8.65251,25.4323 Z "/>

 

 

 

<Path x:Name="Path_3" Width="11.2273" Height="6.11365" Canvas.Left="34.6264" Canvas.Top="23.6968" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FFFFFFFF" Fill="#FFFFFFFF" Data="F1 M 35.1264,29.3105C 35.1264,26.4863 37.4158,24.1968 40.24,24.1968C 43.0642,24.1968 45.3536,26.4863 45.3536,29.3105"/>

 

 

 

<Path x:Name="Path_4" Width="8.52273" Height="8.52271" Canvas.Left="36.0103" Canvas.Top="25.4323" Stretch="Fill" Fill="#FF000000" Data="F1 M 40.2716,25.4323C 42.6251,25.4323 44.533,27.3401 44.533,29.6937C 44.533,32.0472 42.6251,33.955 40.2716,33.955C 37.9182,33.955 36.0103,32.0472 36.0103,29.6937C 36.0103,27.3401 37.9182,25.4323 40.2716,25.4323 Z "/>

 

 

 

</Canvas>

 

 

 

</Canvas>

 

 

 

</Grid>

 

</

 

UserControl>

 

The CodeBehind

using

 

System;

 

using

 

System.Collections.Generic;

 

using

 

System.Linq;

 

using

 

System.Net;

 

using

 

System.Windows;

 

using

 

System.Windows.Controls;

 

using

 

System.Windows.Documents;

 

using

 

System.Windows.Input;

 

using

 

System.Windows.Media;

 

using

 

System.Windows.Media.Animation;

 

using

 

System.Windows.Shapes;

 

namespace

 

DeepEarth

 

{

 

public partial class TruckControl : UserControl

 

{

 

public TruckControl()

 

{

}

}

}

And here's the only code I changed on my copy of the PushPin class. I did change the class name to "Truck" though, instead of "Pushpin".

 

public override UIElement CreateElement(IProjection projection)

 

{

 

//const string xaml = "<Path xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" Width=\"51\" Height=\"29.3058\" Stretch=\"Fill\" StrokeLineJoin=\"Round\" Stroke=\"#FF000000\" Fill=\"#FF000000\" Data=\"F1 M 32.0391,22.5971L 69.2292,22.5971L 69.2292,50.9029L 62.1666,50.8889C 62.1666,47.9894 59.8161,45.6389 56.9166,45.6389C 54.0171,45.6389 51.6666,47.9894 51.6667,50.9029L 34.4583,50.8889C 34.4583,47.9894 32.1078,45.6389 29.2083,45.6389C 26.3088,45.6389 23.9583,47.9894 23.9583,50.9029L 19.2292,50.9029L 19.2292,41.812L 24.0888,38.8892L 31.9236,22.6458L 32.0475,22.8213L 32.0391,22.5971 Z M 25.8958,37.9097L 39.9583,37.8542L 39.9583,23.7708L 32.4262,23.7708L 25.8958,37.9097 Z \"/>";

 

 

//var path = (Path) XamlReader.Load(xaml);

 

 

//UpdateElement(path, projection);

 

 

//return path;

 

 

TruckControl tc = new TruckControl();

 

 

return tc;

 

}

On the create polygon button Icomented out the code to draw the polygon and added code to instantiate the truck control and add it to the shapelayer. When I ran my truck control with the comented code in the "CreateElement" method above, it created a simple black truck, but I really need the one from the TruckControl class.

When I run the project everything loads up, as soon as I click the add polygon button at the botom of the site, I get the usual yelow icon javascript error :[

Thanks
Q
Developer
Sep 6, 2008 at 1:32 AM
Edited Sep 6, 2008 at 1:35 AM
OK, I updated the "DeepEarthPrototype" project...

I made my own Custom Push Pin....

  • My Custom UserControl pin has multi "Paths" in it like you described you would like/needed and is the "Pin.Xaml" file added to the project it also has a CallOut and uses the "VisualStateManager" to Show & Hide the CallOut
  • the other class is the "MyCustomPin.cs" which is just a copy of the "PushPin.cs" class from the DeepEarth project with a small change...

 

   36         public override UIElement CreateElement(DeepEarth.IProjection projection)

   37         {

   38             var customPin = new Pin();

   39             UpdateElement(customPin, projection);

   40             return customPin;

   41         }

   42 

   43         public override void UpdateElement(UIElement element, DeepEarth.IProjection projection)

   44         {

   45             var customPin = (UIElement)element;

   46 

   47             Point pixel = Map.GetProjectionToDisplay(Point);

   48             Canvas.SetLeft(customPin, pixel.X - 12.5);

   49             Canvas.SetTop(customPin, pixel.Y - 25);

   50         }

  • I made my own "CustomPinBehavior.cs", the standard "PrototypeBehaviour.cs" is what handles the detection of "ALT + Mouse Click" to add a "PushPin" my "CustomPinBehavior.cs", basically does the same but adds my own Custom/UserControl Pin and added it in the page.cs file..
    e.g.

   24             // map.EventBehavior.List.Insert(0, new PrototypeBehavior());

   25             // Add MyCustomPin Behaviour to EventBehavior List

   26             map.EventBehavior.List.Insert(0, n ew CustomPinBehavior());

  • I uploaded the project so you can check it all out at:  http://davidthiessen.com/DeepEarthPrototype.zip
  • Also please note that the Custom Pin right now does not "Scale" when you zoom in and out
  • and I also just added a button on the map so you can add a Custom pin just like the polygon, but it just adds to the center of the map right now, I did not pass any coords in with it from the button
  • And right now you need to seem to click the custom pin once to make the CallOut show & hide..?
Developer
Sep 6, 2008 at 2:41 AM
project using your "TruckControl" pin, I did not add a callout to your control, but you can see it is the other project

http://davidthiessen.com/DeepEarthPrototype_TruckPin.zip
Sep 8, 2008 at 1:23 AM
Thanks guys! This was really helpful and i was able to get what i was asking for.
I am planning to make the opacity of the pushpin to 1 only at zoom level > 6. Is there a way to find out the zoom level as we zoom the map?
Can you please share the snippet with me.

Thanks

Developer
Sep 8, 2008 at 2:31 AM

   43         public override void UpdateElement(UIElement element, DeepEarth.IProjection projection)

   44         {

   45             var customPin = (UIElement)element;

   46 

   47             if (Map.ZoomLevel <= 6)

   48             {

   49                 // customPin.SetValue(UserControl.OpacityProperty, 0.0);

   50                 customPin.Opacity = 0.0;

   51             }

   52             else

   53             {

   54                // customPin.SetValue(UserControl.OpacityProperty, 100.0);

   55                 customPin.Opacity = 100.0;

   56             }

   57 

   58             Point pixel = Map.GetProjectionToDisplay(Point);

   59             Canvas.SetLeft(customPin, pixel.X - 12.5);

   60             Canvas.SetTop(customPin, pixel.Y - 25);

   61         }


Each time you zoom the map in or out, the "UpdateElement" method in your "TruckPin" class will fire
there you can check the "Map.ZoomLevel" property and set the Opacity

I am not sure if it is better to use the "SetValue" way or just set the property...
but both lines below will work

 

customPin.SetValue(

UserControl.OpacityProperty, 0.0);

 

customPin.Opacity = 0.0;

 

 

<!--EndFragment-->
Sep 8, 2008 at 7:19 AM
Edited Sep 8, 2008 at 10:05 AM
Thank you all so much for your feedback!!! I eventually added the control to the layout grid, which was not quite yielding the results that I was looking for. Going to have a look at the links that DotNetNoobie provided :]

For the record, the max on the opacity is 1, not 100 :) I copied the code into my truck class and didn't understand why the opacity was not acurate on 10, then remembered that opacity is usualy a number between 0 and 1.
Developer
Sep 8, 2008 at 2:54 PM
Just FYI from dotnetnoobie's response: You can use SetValue or just set the property as they both do the same thing (as you have mentioned). Setting the property (customPin.Opacity = 0;) simply calls the SetValue() under the covers; it is just shorthand notation. The typical way to set values is to set the property (customPin.Opacity = 0;). You will see .SetValue() and .GetValue() used when custom properties are defined for their 'get' and 'set' properties when those properties are DependancyProperties. Either way, both work and the choice is up to the developer.