MapPoint Forums

MapForums

Community of VE/MapPoint Users and Developers




Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (6/6)

This is a discussion on Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (6/6) within the Virtual Earth Blogs forums, part of the Blogs category; Inserting data into SQL Server 2008 In the previous parts we have first been looking on the database side and ...


Go Back   MapPoint Forums > Blogs > Virtual Earth Blogs

Register Blogs FAQ Members List Calendar Search Today's Posts Mark Forums Read
  3 links from elsewhere to this Post. Click to view. #1 (permalink)  
Old 03-22-2008
Member
Green Belt
 
Join Date: Sep 2007
Posts: 50
Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (6/6)

Inserting data into SQL Server 2008

In the previous parts we have first been looking on the database side and how we can use various mechanisms to load and extract data and we even implemented a geocoder in the database. Then we moved on and investigated various ways to retrieve data from SQL Server 2008 and visualize them in Virtual Earth. In this final part we will now focus on using Virtual Earth as a simple data editor which allows us to write data back to SQL Server 2008.

We will implement the data editor in form of a query builder. In the user interface we will have some drawing tools which allow us to draw points, lines, polygons and circles on the map and to store them temporarily in our browser window. Each of the temporarily stored geographies will have a checkbox next to it and when we check these boxes we will dynamically create a SQL statement which automatically determines the appropriate feature-type. The SQL-statement will be displayed in a textarea and we will be able to manually edit it.

Once we click on the image with the SQL Server logo we will create an AJAX-call which sends the SQL-statement via HTTP-Post request to a HTTP handler and this handler will actually execute the statement.



[IMG]http://blufiles.storage.msn.com/y1pLfDzppuxasgWQquQZMiRZNaAbTz5BrThUjhwyS5sFtPv9oE OsbKX3Ww9jrR2yqAh912IvTcBZto?PARTNER=WRITER
[/IMG]

Let’s start with a fresh table in our SQL Server. We create a table with a column of type geography.

CREATE TABLE [FeatureDemo]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[Geom] geography NULL,
CONSTRAINT [PK_FeatureDemo] PRIMARY KEY CLUSTERED
(
[id] ASC
)
) ON [PRIMARY]

In our ASP.NET page we first add a new accordion pane. This pane first displays a notice which reminds you that drawings which shall be added as a geography data type to the database must be drawn counter-clockwise. It also hosts buttons to draw various types of geographies and textboxes which will display the latitude and longitude under the mouse-cursor.

In the “Geometry”-section it provides 2 links: delete all drawings and reset the SQL statement in the textarea. Finally there is an empty DIV-element in which we will temporarily store our drawing objects with a checkbox next to them:

<cc1:AccordionPane ID="paneQueryBuilder" runat="server">
<
Header>Query BuilderHeader>
<
Content>
<
b>Drawing Toolsb><br /><br />
<
i>Please make sure, you draw the polygon counter-clockisei><br /><br />
<
input id="btnPoint" type="button" value="Point" onclick="Draw('point')" style="width: 125px;" />
<
input id="btnPolyline" type="button" value="Polyline" onclick="Draw('polyline')" style="width: 125px;" /><br />
<
input id="btnPolygon" type="button" value="Polygon" onclick="Draw('polygon')" style="width: 125px;" />
<
input id="btnCircle" type="button" value="Circle" onclick="Draw('circle')" style="width: 125px" /><br /><br />
<
a style="font-family:Courier New">Lat: a><input id="txtLat" type="text" disabled="disabled" style="width: 210px" class="TxtBox" /><br />
<
a style="font-family:Courier New">Lon: a><input id="txtLon" type="text" disabled="disabled" style="width: 210px" class="TxtBox" /><br /><br />
<
b>Geometriesb><br />
<
a href='javascripteleteAll()'>Delete All a>
<
a href='javascript:ResetQuery()'>Reset SQL-Querya><br />
<
div id="divGeom">div>
Content>
cc1:AccordionPane>

We will also need some more DIV-elements for the interaction with our geographies as well as the visualization and the editing of our SQL statement. Below you find the ASP.NET sources for a textarea where the SQL statement will be displayed, a clickable image which allows us to execute the AJAX-call as well as 2 elements which display the length of polylines and polygons while we draw as well as a dialog which allows us to enter the title and description of a geography.

<textarea id="txtSQL" rows="2" style="position:absolute; left:300px; bottom:5px; width:300px; height:94px" >textarea>
<
img src="IMG/Katmai.png" alt="Execute SQL-Statement" style="position:absolute; bottom:5px; right:5px; cursorointer;" onclick="SqlInsert();"/>
<
div id='divDistance' style="position:absolute; left:10px; top:800px; visibility:hidden;" class="TxtBox";>div>
<
div id='divShapeInfo' style="position:absolute; left:10px; top:850px; visibility:hidden;" class="TxtBox";>
<
b><u>Please enter the details:u>b><br /><br />
<
a>ID         : a><input id="txtShapeID" type="text" disabled="disabled" style="width: 150px" /><br />
<
a>Title      : a><input id="txtShapeTitle" type="text" style="width: 150px" /><br />
<
a>Description: a><input id="txtShapeDetails" type="text" style="width: 150px" /><br /><br />
<
input id="btnShapeInfo" type="button" value="Set" onclick="SetInfo()" style="width: 260px"/><br />
div>

If we click a button to draw a geography we change the cursor to a crosshair and attach an onclick- and an onmousemove-event to the map. While we move the mouse we continuously update the latitude and longitude in the textboxes on the accordion pane. When we click with the left mouse-button we add a point to our temporary geography. If the geography is a polyline or polygon we will also determine the length of the line. For a circle the value in the divDistance will be the radius.



[IMG]http://gkxu3a.blu.livefilestore.com/y1psLOdC392akqCy22_Uqtlr3G8xf_zALGeihHJeWBft4s_q45 WlR2uTaRFnM9wHfbtdVTLKdDRnMsX95EEMqmDjA?PARTNER=WR ITER
[/IMG]

To finish the drawing we will hit the right mouse-button. This will detach the map-events and also bring up the divShapeInfo so that we can enter a title and a description. The distance will automatically be added to the shape.



[IMG]http://gkxu3a.blu.livefilestore.com/y1pYZrCEXzy6WEU0RdHWSRkYYBTSHd3F7hwvzCLDeVZY8Pv14o dmR96lm04hucCXk7QdICg5xQKdndC2nLsBnFgMV3EVbKP-WWU?PARTNER=WRITER
[/IMG]

When we click on “Set” in the dialogue above we will add the geography to our divGeom in the accordion pane. Next to the geography we have a checkbox and a JavaScript-function will update the textarea txtSQL with a statement appropriate for the selected geometries. For example if we have a polygon the statement will reflect that, if we have 2 polygons the statement will show a MULTIPOLYGON and if we have 2 polygons and a point the statement will show a GEOMETRYCOLLECTION.


[IMG]http://gkxu3a.blu.livefilestore.com/y1pYZrCEXzy6WEuKU8TWPHLlv8nkY74BOd2TbbjCaBD_wxtk3G C2h_sWoc0eI7WADsZ9RXt3vQt1yQQjZTBLGwnGwNXS5LS35r3? PARTNER=WRITER
[/IMG]

The drawing part on top of Virtual Earth leverages a couple of events which can be attached to the Virtual Earth Map and I published the complete code on Via Virtual Earth. So I don’t want to go into detail for this part.

[I just noticed that this sample has been removed so now you'll find it here].

The major difference between the code on “Via Virtual Earth” and the code in this sample application is that we create an additional checkbox with an onclick-event attached. Once we activate the checkbox we call a function to update the SQL statement in the textarea:

function SetInfo()
{
myCurrentShape.SetTitle(document.getElementById("txtShapeTitle").value);
myCurrentShape.SetDescription(document.getElementB yId("txtShapeDetails").value + "
Delete"
);

document.getElementById("divGeom").innerHTML = document.getElementById("divGeom").innerHTML +
"" + document.getElementById("txtShapeTitle").value + "
"
;

myPoints = new Array();
tempPoints = null;
myDistance = 0;
tempDistance = 0;

document.getElementById("divShapeInfo").style.visibility = "hidden";
document.getElementById("txtShapeTitle").value = "";
document.getElementById("txtShapeDetails").value = "";
}

Updating the SQL-statement in the textarea requires first to determine the types of the VEShape-objects which have been activated.

function UpdateSQLQuery(id)
{
var currentShape = slDrawing.GetShapeByID(id.id);
switch (currentShape.GetType())
{
case "Point":
pointCount++;
var tempArray = currentShape.GetPoints();
for(var j = 0; j < (tempArray.length); j++)
{
pointArray.push(tempArray[j].Latitude + " " + tempArray[j].Longitude);
}
break;
case "Polyline":
polylineCount++;
var tempArray = currentShape.GetPoints();
var dummy = "";
for(var j = 0; j < (tempArray.length); j++)
{
dummy = dummy + tempArray[j].Latitude + " " + tempArray[j].Longitude + ", ";
}
dummy = dummy.substr(0, dummy.length - 2);
polylineArray.push(dummy);
break;
case "Polygon":
polygonCount++;
var tempArray = currentShape.GetPoints();
var dummy = "";
for(var j = 0; j < (tempArray.length); j++)
{
dummy = dummy + tempArray[j].Latitude + " " + tempArray[j].Longitude + ", ";
}
dummy = dummy.substr(0, dummy.length - 2);
polygonArray.push(dummy);
break;
}

Now we determine which type of geography in SQL Server 2008 matches our selection.

if (pointCount == 1 && polylineCount == 0 && polygonCount == 0) geomType = "POINT";
else if (pointCount > 1 && polylineCount == 0 && polygonCount == 0) geomType = "MULTIPOINT";
else if (pointCount == 0 && polylineCount == 1 && polygonCount == 0) geomType = "LINESTRING";
else if (pointCount == 0 && polylineCount > 1 && polygonCount == 0) geomType = "MULTILINESTRING";
else if (pointCount == 0 && polylineCount == 0 && polygonCount == 1) geomType = "POLYGON";
else if (pointCount == 0 && polylineCount == 0 && polygonCount > 1) geomType = "MULTIPOLYGON";
else geomType = "GEOMETRYCOLLECTION";

Finally we create our SQL-statement.

 switch (geomType)
{
case "POINT":
sqlBuilder = "INSERT INTO FeatureDemo (Geom) VALUES (geography::STGeomFromText('POINT (" + pointArray[0] + ")', 4326))";
document.getElementById("txtSQL").value = sqlBuilder;
break;
case "MULTIPOINT":
var dummy = "";
for(var j = 0; j < (pointArray.length); j++)
{
dummy = dummy + pointArray[j] + ", ";
}
dummy = dummy.substr(0, dummy.length - 2);
sqlBuilder = "INSERT INTO FeatureDemo (Geom) VALUES (geography::STGeomFromText('MULTIPOINT (" + dummy + ")', 4326))";
document.getElementById("txtSQL").value = sqlBuilder;
break;
case "LINESTRING":
sqlBuilder = "INSERT INTO FeatureDemo (Geom) VALUES (geography::STGeomFromText('LINESTRING (" + polylineArray[0] + ")', 4326))";
document.getElementById("txtSQL").value = sqlBuilder;
break;
case "MULTILINESTRING":
var dummy = "";
for(var j = 0; j < (polylineArray.length); j++)
{
dummy = dummy + "(" + polylineArray[j] + "), ";
}
dummy = dummy.substr(0, dummy.length - 2);
sqlBuilder = "INSERT INTO FeatureDemo (Geom) VALUES (geography::STGeomFromText('MULTILINESTRING (" + dummy + ")', 4326))";
document.getElementById("txtSQL").value = sqlBuilder;
break;
case "POLYGON":
sqlBuilder = "INSERT INTO FeatureDemo (Geom) VALUES (geography::STGeomFromText('POLYGON ((" + polygonArray[0] + "))', 4326))";
document.getElementById("txtSQL").value = sqlBuilder;
break;
case "MULTIPOLYGON":
var dummy = "";
for(var j = 0; j < (polygonArray.length); j++)
{
dummy = dummy + "((" + polygonArray[j] + ")), ";
}
dummy = dummy.substr(0, dummy.length - 2);
sqlBuilder = "INSERT INTO FeatureDemo (Geom) VALUES (geography::STGeomFromText('MULTIPOLYGON (" + dummy + ")', 4326))";
document.getElementById("txtSQL").value = sqlBuilder;
break;
case "GEOMETRYCOLLECTION":
var dummy = "";
if (pointArray.length > 0)
{
for(var j = 0; j < (pointArray.length); j++)
{
dummy = dummy + "POINT(" + pointArray[j] + "), ";
}
}
if (polylineArray.length > 0)
{
for(var j = 0; j < (polylineArray.length); j++)
{
dummy = dummy + "LINESTRING(" + polylineArray[j] + "), ";
}
}
if (polygonArray.length > 0)
{
for(var j = 0; j < (polygonArray.length); j++)
{
dummy = dummy + "POLYGON((" + polygonArray[j] + ")), ";
}
}
dummy = dummy.substr(0, dummy.length - 2);
sqlBuilder = "INSERT INTO FeatureDemo (Geom) VALUES (geography::STGeomFromText('GEOMETRYCOLLECTION (" + dummy + ")', 4326))";
document.getElementById("txtSQL").value = sqlBuilder;
break;
}
}

Now that we have drawn our geographies and dynamically created our SQL-statement we only need to execute it. As in previous examples we will use an AJAX-call but unlike in the previous examples we will use an HTTP-Post request since the SQL-statements with all the coordinates can become quite long.

function SqlInsert()
{
//Get the appropriate XMLHTTP object for the browser
var xmlhttp = GetXmlHttp();

//if we have a valid XMLHTTP object
if (xmlhttp)
{
xmlhttp.open("POST", "./Insert.ashx", false);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//set the callback
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readystate ==4) //4 is a success
{
//server code creates JavaScript "on the fly" for us to
//execute using eval()
var result = xmlhttp.responseText
eval(result);
}
}
xmlhttp.send("sql=" + document.getElementById("txtSQL").value);
}
}

The HTTP-handler which is being called by the AJAX-call is even simpler than anything we had before. We just fetch the SQL-statement from the, set up the database connection and execute the statement. A message will be returned to the AJAX-call to indicate success or possible problems with the statement.

'Fetch URL-parameter
Dim mySQL1 As String = context.Request.Params("sql")

'Prepare database
Dim settings As ConnectionStringSettings = ConfigurationManager.ConnectionStrings("SpatialDB")

Dim myConn1 As New SqlConnection(settings.ConnectionString)
myConn1.Open()
Dim myCMD1 As New SqlCommand(mySQL1, myConn1)

Try
myCMD1.ExecuteNonQuery()
context.Response.Write("alert('SQL-Statement Executed');")
Catch ex As Exception
context.Response.Write("alert(" + """" + ex.Message + """" + ");")
End Try

All right, we’re done. Run your page and test it.



You can also retrieve the results within SQL Server Management Studio...

SELECT Geom.STAsText() FROM FeatureDemo
---------------------------------------
POINT (51.461166621237787 -0.9271699190139665)
MULTIPOINT ((51.461149909867657 -0.9271699190139665), (51...))
POLYGON ((51.461380526235004 -0.92682123184203891, 51...))
MULTIPOLYGON (((51.461380526235004 -0...))((...)))

…and do further analysis like determining the size of the area which is covered by a polygon.

SELECT Geom.STArea() FROM FeatureDemo WHERE ID = 4
--------------------------------------------------
2532.6 square meter

Note: Polygons must be drawn counter clockwise and each polygon figure must be within a single, logical hemisphere. Individual spatial objects do not need to be within the same logical hemisphere in order to run spatial operations between them.

*



Click here to view the article.

Last edited by Eric Frost; 03-22-2008 at 05:54 PM.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!Spurl this Post!Reddit! Wong this Post!
Reply With Quote
Reply


LinkBacks (?)
LinkBack to this Thread: http://www.mapforums.com/virtual-earth-sql-server-2008-part-4-integrating-sql-server-2008-virtual-earth-6-6-a-7346.html

Posted By For Type Date
The Magazine for MapPoint - MP2K Magazine This thread Refback 03-27-2008 08:42 AM
Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (6/6) - MapPoint Forums This thread Refback 03-26-2008 05:57 PM
Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (6/6) - MapPoint Forums This thread Refback 03-26-2008 05:57 PM

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads

Thread Thread Starter Forum Replies Last Post
Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (4/6) Johannes Kebeck's Blog Virtual Earth Blogs 0 03-03-2008 12:51 PM
Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (3/6) Johannes Kebeck's Blog Virtual Earth Blogs 0 03-02-2008 03:52 PM
Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (2/6) Johannes Kebeck's Blog Virtual Earth Blogs 0 03-02-2008 03:52 PM
Virtual Earth & SQL Server 2008 - Part 4: Integrating SQL Server 2008 and Virtual Earth (1/6) Johannes Kebeck's Blog Virtual Earth Blogs 0 03-02-2008 03:52 PM
Virtual Earth & SQL Server 2008 - Part 2: Spatial Data Management in SQL Server 2008 (3/3) Johannes Kebeck's Blog Virtual Earth Blogs 0 03-02-2008 01:40 PM


All times are GMT -5. The time now is 01:31 PM.


Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5
MP2K Magazine
Visitor Map

Cheap Flights Paphos
Have a fantastic holiday in Paphos. Enjoy the lively seafront atmosphere and the picturesque mediaeval port. Book cheap flights online at Holiday Hypermarket.

Italy Holidays
Find and book Italy Holidays with Travel Counsellors. Holiday destinations around the world including Italy.

Holiday in Turkey
A Holiday in Turkey is great value when you book with dealchecker.co.uk. There is an abundance of things to see and do. Check out the well-preserved Greco-Roman ruins.

Holidays in Egypt
A holiday in Egypt will stimulate your mind, captivate your heart and spark your senses. Visit this exceptional country, book today!

Cyprus
Before visiting Cyprus, make sure you are well informed to make the most of your holiday. Online at ulookubook.com you check out our useful travel guides. Find out all about the Cyprus nightlife, shopping, eating and customs.

All inclusive holiday
Travel.co.uk is a travel comparison service which makes it easy to search and find your all inclusive holiday.

Holidays in Goa
Want to know more about Indian culture? Visit On The Beach for information on holidays in Goa.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52