The products listed above, and their associated names, icons and logos, are the intellectual property of Microsoft Corporation.
Rate this Article
Average Rating: 
Whole StarWhole StarWhole StarWhole StarHalf Star
Total number of ratings: 5
Leave your own rating
VEMap with geoRSS

The objective is to use Virtual map in a way similar to Live Map. Livemap allows user to create push pins and save it in a collection. This collection is used to reload the map whenever we use Livemap again. Its possible to use these collection for your own VE Map application, but there is no way we can add more shapes to Collection or modify the Collection data using VE map methods. Another alternative is to use geoRSS to load the shape data.

geoRSS gives us the flexibility to modify and customize shape data based on specific application requirements. So in case we need to show a user his own push pins every time the person logs in geoRSS is the best option.

We will try to accomplish the following here.

  • Displaying a map

  • Giving user the ability to create pushpins

  • Save the Pushpins to database.

  • Create a geoRSS using Pushpin data

  • Re Load the Map with geoRSS

Displaying the Map:

First, lets display the map by our regular getmap() function.

On Body on load we will call GetMap()  and on unload  DisposeMap()

You will need to define the variables with your style and mode. This is no big deal, just refer the Method samples mentioned in Sdk.

function GetMap()
  {
var latLon = new VELatLong(document.getElementById('txtLat').value, 
document.getElementById('txtLong').value);
map = new VEMap('myMap');
map.LoadMap(latLon, zoom, selStyle, fixed, selMode, showSwitch);
...

txtLat and txtLong are two text boxes in the body inside a Form that stores a default latitude and longitude. The map will load with this point as default. Next, we need to attach the click event.

map.AttachEvent('onclick', MapClick);

Giving user the ability to create pushpins

MapClick(e)  will need to capture the pixelpoint of the clicked location. This is the location where we are going to add a PushPin. You will be using  e.mapX and e.mapY to xPoint and yPoint Variables. Next, with xPoint and yPoint  we get the Pixel and with the Pixel the Longitude and Latitude. Its quite simple. In real life you should think of implementing this in a slightly advanced way by showing a Context menu on Rightclicking the map and user selecting the option "Add a PushPin" or something like that. Its just pure javascript and I won't be going there today.

xpoint = e.mapX;
ypoint = e.mapY;
pixel = new VEPixel(xpoint,ypoint);
var LL = map.PixelToLatLong(pixel);
cornerOne = LL; //cornerOne is a global level var.
latitude = map.PixelToLatLong(pixel).Latitude;
longitude = map.PixelToLatLong(pixel).Longitude;

So now we know the Point where user wants to add the Pushpin. Next step is to ask details about the Point. Just like Live Map we will Popup a window here to get the Name and Description of the Point. 

newwindow=window.open("Pindetails.htm","PinDetails","width=300,height=330"); 
 }

Pindetails.htm has a Form with a Text box control for name and a TextArea control for Description. On Submit of this Form, the Popup closes and sends the data to Parent page hidden fields. You will need a javascript function in Pindetails page to send the data and another one in Parent page to accept them.

Pindetails Script:

 function SendValueToMap()
    {var myVal = document.getElementById("PinName").value;
     var mydesc = document.getElementById("Pindescr").value;
    window.opener.GetValueFromPop(myVal,mydesc);
       window.close();
            return false;   }

Parent Map Page Script:

function GetValueFromPop(myVal,mydesc) 
{ document.getElementById("defaultbox").value = myVal; 
document.getElementById("defaultdesc").value = mydesc;
 AddShape(); 
}

You would notice that I called the Addshape() in the same function. Yes, now we will Add the Pushpin to the Point clicked with the Name and description collected from the Pindetails Form.  We will use the variable CornerOne defined earlier to place the Pushpin. Then get the name and description to show the details of the Pin. You could enhance by adding more data controls here if you need to capture the User details etc. I would imagine so because most of the time we need to know who added this Pushpin. While loading the Map later, you could load based on User also in that way. Lets go to Adding the Shape now.

 function AddShape()
          {                   
 veNewPinDetails = document.getElementById("defaultdesc").value;
 c1Shape = new VEShape(VEShapeType.Pushpin, cornerOne);
 c1Shape.SetTitle('<B>'+ document.getElementById("defaultbox").value +'</B>');
 c1Shape.SetDescription('<div style="width: 200px; background-color: white; color: blue">' +
veNewPinDetails + '</div>');
 map.ClearInfoBoxStyles();
 map.AddShape(c1Shape);

This will display the Pin on the Map. If you point the mouse on the Pin Icon a callout with details entered by the user will also be shown.

Next we will populate the hidden fields on the Page Form with values. Form Name is saveNewPoints and it should have attributes runat ="server" and onsubmit="saveNewPointsinDb"

// Populate the Hidden variables with value
 document.getElementById("HiddenField1").value=
document.getElementById('defaultbox').value.toString();
  document.getElementById("HiddenField2").value=
document.getElementById('defaultdesc').value.toString();
  document.getElementById("HiddenField3").value= latitude.toString();
  document.getElementById("HiddenField4").value= longitude.toString();

Save the Pushpins to database.

Last step of Addshape() is to call the saveNewPoints Form Submit function. This is the Form where we have all the Hiddenfields with Pinname, Description,Longitude, Latitude etc. So submitting this form will refresh the Page too. On Form Submit() a C# method from the CodeBehind will get executed.

document.saveNewPoints.submit();

This will invoke the C# codeBehind method  saveNewPointsinDb. This method will fetch the control values from the aspx page and save it to database, just the plain simple Form Submission stuff. I am leaving out this part here for you to implement.

 Create a geoRSS using Pushpin data

This is going to be interesting. Now we have data for the user created Pushpins in our database. We need to create geoRSS ON THE FLY and pass it to Map. Remember geoRSS has a strict XML format and it should confirm to that. If you need to know more about geoRSS version 2.0 you could check the specification and samples on the net.

Here is a sample geoRSS to show you how it looks like.

<?xml version="1.0" ?> 
<rss version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
<item>
<title>My Home</title>
<description>This is my home</description>
<geo:lat>9.70</geo:lat><geo:long>-27.60</geo:long>
</item>
</channel>
</rss>

The Rss file has Channel and Item defined to show the Points on the Map. You should understand that, Microsoft is very clear about the use of Geo codes obtained from Bing. You should be using them only in Microsoft Map Products. Before using this in Production you should have a discussion with Microsoft to reach an SLA too.

So now we will write an XML output from our database in geoRSS Format. We won't be writing to a physical XML file here instead, the aspx page will output the XML everytime its executed.The header of the aspx should have ContentType="text/xml"

Here is how you could do this in C#. You will need to refer System.Xml here. I have omitted the datbase connection part and the dataset operations.

  protected void Page_Load(object sender, EventArgs e)
    {
  //Open your db connection
  //get a dataset with geoRSS data populated.
  //lets call the dataset geoRSSds
   Response.ContentType = "text/xml";
    
    XmlTextWriter writer = new XmlTextWriter(Response.OutputStream,null);
    writer.WriteStartDocument();
    writer.WriteStartElement("rss");
    writer.WriteAttributeString("version", "2.0");
    writer.WriteAttributeString("xmlns:geo", "http://www.w3.org/2003/01/geo/wgs84_pos#");
     writer.WriteStartElement("channel");
        //if geoRSSds is not null and rows count >0 then
        //For each loop for geoRSSds starts here {
            writer.WriteStartElement("item");
            writer.WriteElementString("title", pointName);
            writer.WriteElementString("description", pointDescription);
            writer.WriteElementString("geo:lat", geoLat);
            writer.WriteElementString("geo:long", geoLong);
            writer.WriteEndElement();
        // } For each loop ends here
            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Close();
     }

ReLoad the Map with geoRSS

Now that we have a geoRSS, Virtual Map is to be reloaded using this. The getMap() function needs to have the below appended.

  var l = new VEShapeLayer();
  var url = "http://localhost/vePrototype/getgeoRSSpage.aspx"
  var veLayerSpec = new VEShapeSourceSpecification(VEDataType.geoRSS, url, l);
  map.ImportShapeLayerData(veLayerSpec, onFeedLoad);

Here in VEShapeSourceSpecification method the type is specified as a geoRSS file. The getgeoRSSpage.aspx will get the geoRSS XML dynamically from the database and pass it to this method. So the Map loads with the PushPins created by user.

The Callback function onFeedLoad could be used for many purposes. I am using it to ask the Map to zoom on to the last point saved on the Map.

function onFeedLoad(layer)
   {
 var latLon = new VELatLong(document.getElementById('txtLat').value,
document.getElementById('txtLong').value);
  map.SetCenterAndZoom(latLon,14);
   }
    

 Conclusion:

There are many different possible applicable scenarios for this. You could load the map based on User logged in. or you could add further methods to remove the Pushpins from Map and database. Using geoRSS gives Bing Maps the flexibility to suit specific business scenarios where users could choose what data they need to point on the Map.

 Article by : Honey krishnan Poomalaveetil

Copyright 2009. Sponsored by nsquared.   |  Terms Of Use  |  Privacy Statement
Content on this site is generated from the developer community and shared freely for your enjoyment and benefit. This site is run independently of Microsoft and does not express Microsoft's views in any way.