In the spirit of my "Mixing OOP and Event Driving Programming" article I posted a couple days ago; this article discusses how to implement the same thing using the ASP.NET AJAX JavaScript Library. Using inheritence (the ASP.NET AJAX way) it is even easier to implement a little Event Driven Model into your client-side, JavaScript classes/components.
Event Driven Basics
First we'll start by creating a Person class that inherits from the Sys.Component class. Now remember, since we are doing things the ASP.NET AJAX way, we aren't using JavaScript's Prototypal Inheritence.
Person = function() {
Person.initializeBase(this);
};
Person.prototype = {
initialize: function() {
Person.callBaseMethod(this, "initialize");
},
dispose: function() {
Person.callBaseMethod(this, "dispose");
}
};
Person.registerClass("Person", Sys.Component);
At first glance you may notice that there's a little more plumbing required to inherit from another object using ASP.NET AJAX. This is true, however it does make implementing Events much easier. The magic of inheritence mostly occurs within the call to the "registerClass" method that actually sets up the class/object to inherit from "Sys.Component." It also sets up the "initialize" method to be called when the object is instantiated.
If you have question (and I'm sure you do if you're not familiar with ASP.NET AJAX), please go check out the ASP.NET AJAX Documentation, as further details aren't within the scope of this article.
Now, the hash table that we implemented in the previous article is already implemented for us within the "Sys.Component" class. We can access it using the "private" "get_events" method. The "get_events" method actually returns an instance of the"Sys.EventHandlerList" class that also implements the "getHandler" method for us. This all makes implementing Events much simpler.
First, lets create a "raiseEvent" method, since this isn't created for us. This method will allow us to actually Raise the Events with only a single method call.
Person.prototype = {
raiseEvent: function(eventName, eventArgs) {
var handler = this.get_events().getHandler(eventName);
if (handler) {
if (!eventArgs) {
eventArgs = Sys.EventArgs.Empty;
}
handler(this, eventArgs);
}
}
};
Now lets add the "Name" property (with accessors) to our Person class, and have the "set" accessor Raise the "onchangename" event:
Person.prototype = {
get_Name: function() {
return this._name;
},
set_Name: function(value) {
// get old value
var oldValue = this._name;
// set new value
this._name = value;
// Raise the Event and send the old value as the "EventArgs"
this.raiseEvent("onchangename", oldValue);
}
};
Here's an example of using the Person class, and attaching a function to handle the "onchangename" event:
var p = new Person();
p.get_events().addHandler(
"onchangename",
function(sender, eventArgs) {
alert("Old Value: " + eventArgs);
}
);
p.set_Name("Charlie");
As you can see in the example event handler that we added above, the
function gets passed two parameters (sender and eventArgs). The sender
is the Person object that is raising the event, and the eventArgs is this events arguments. So far we are only passing the old Name value as the event arguments, but in the next section of the article we'll see how to create our own EventArgs object that inherits from "Sys.EventArgs" that can contain anything we want to pass to the event handler.
Go Further With Sys.EventArgs
The proper way to raise events in ASP.NET AJAX, is to pass an instance of "Sys.EventArgs" when raising events. This allows you to pass any event arguments to the event handler that you want/need. This also follows suit after the way Events are handled within the .NET Framework.
To do this, we'll first create our own custom EventArgs class that inherits from "Sys.EventArgs", and we'll add "OldName" and "NewName" read-only properties to it (to do this we'll only add 'get' accessors). We'll set the "OldName" and "NewName" properties within the constructor, so we'll make the constructor accept those as well.
PersonEventArgs = function(oldNameValue, newNameValue) {
this._oldName = oldNameValue;
this._newName = newNameValue;
};
PersonEventArgs.prototype = {
get_OldName: function() {
return this._oldName;
},
get_NewName: function() {
return this._newName;
}
};
PersonEventArgs.registerClass("PersonEventArgs", Sys.EventArgs);
Now to make use of this new PersonEventArgs class, we just need to change the line of code within the Person class's "Name" properties accessor to the following:
this.raiseEvent("onchangename", new PersonEventArgs(oldValue, this._name));
Now to access the "OldName" and "NewName" properties of the PersonEventArgs when they are passed to the "onchangename" event handler, just call their property accessors. Like the following:
var p = new Person();
p.get_events().addHandler(
"onchangename",
function(sender, eventArgs) {
alert("Old Name: " + eventArgs.get_OldName();
alert("New Name: " + eventArgs.get_NewName();
});
Simplify the Adding of Event Handlers
Having to call the "get_events" method, the calling the "addHandler" method and passing it the name of the event can be a little cumbersome. You can create "add_{eventName}" methods that accept one argument (the event handler method) that will add the event handler for you with only one method call, and never needing to pass (and type or misstype) the event name. This is actually how the objects within the ASP.NET AJAX JavaScript library handle adding events. They also implement a "remove_eventName" method that does the same, but removes the event handler passed in.
Person.prototype = {
add_changeName: function(handler) {
this.get_events().addHandler("onchangename", handler);
},
remove_changeName: function(handler) {
this.get_events().removeHandler("onchangename", handler);
}
};
If you compare the below example of adding an event handler for the "onchangename" event, you'll see that it is much simpler to call these methods than the example above.
var p = new Person();
p.add_changeName(function(sender, eventArgs) {
alert("Old Name: " + eventArgs.get_OldName();
alert("New Name: " + eventArgs.get_NewName();
});
Complete Source Code
Heres' the complete code for the Person object created with this article.
First, the example usage code:
var p = new Person();
p.add_changeName(function(sender, eventArgs) {
alert("Old Name: " + eventArgs.get_OldName());
//alert("New Name: " + eventArgs.get_NewName());
});
p.set_Name("Charlie");
p.set_Name("Chris");
And, now the full Person and PersonEventArgs code:
Person = function() {
Person.initializeBase(this);
this._name = null;
};
Person.prototype = {
initialize: function() {
Person.callBaseMethod(this, "initialize");
},
dispose: function() {
Person.callBaseMethod(this, "dispose");
},
raiseEvent: function(eventName, eventArgs) {
var handler = this.get_events().getHandler(eventName);
if (handler) {
if (!eventArgs) {
eventArgs = Sys.EventArgs.Empty;
}
handler(this, eventArgs);
}
},
// Property Accessors
get_Name: function() {
return this._name;
},
set_Name: function(value) {
// get old value
var oldValue = this._name;
// set new value
this._name = value;
// Raise the Event and send the old value as the "EventArgs"
this.raiseEvent("onchangename", new PersonEventArgs(oldValue, this._name));
},
add_changeName: function(handler) {
this.get_events().addHandler("onchangename", handler);
},
remove_changeName: function(handler) {
this.get_events().removeHandler("onchangename", handler);
}
};
Person.registerClass("Person", Sys.Component);
PersonEventArgs = function(oldNameValue, newNameValue) {
this._oldName = oldNameValue;
this._newName = newNameValue;
};
PersonEventArgs.prototype = {
get_OldName: function() {
return this._oldName;
},
get_NewName: function() {
return this._newName;
}
};
PersonEventArgs.registerClass("PersonEventArgs", Sys.EventArgs);
Conclusion
As you can see, it's event easier to add/handle events with your custom classes when you use the ASP.NET AJAX library, rather than implementing it completely yourself. Either way you can use inheritence to greatly simplify things.
Be the first to rate this post - Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
To expand on my previous article on how to create Objects in JavaScript using Prototypal Inheritence, this article will show you how to implement Event Driven Programming with those objects. Implementing Event Driven Programming in JavaScript sounds difficult, but it's actually rather simpel to implement.
To keep with the Prototypal Inheritence theme, we'll create an "EventObject" class that will have the plumbing necessary for implementing Events, and then we'll inherit that class with a simple "Person" class that will have an "onnamechanged" event.
How To Mix OOP and Event Driven Programming in JavaScript
Here's the base EventObject class and Person class with a Name Property (via GetName and SetName property accessors):
EventObject = function() {};
EventObject.prototype = {};
Person = function(name) {
this._name = name;
};
Person.prototype = new EventObject;
Person.prototype.GetName = function() {
return this._name;
};
Person.prototype.SetName = function(value) {
this._name = value;
};
Now, here's some basic example code for using the the Person class:
// Create an instance of the Person Object
var myPerson = new Person("John McCain");
// Get the Name currently set
alert(myPerson.GetName());
// Set the Name Property to a different name
myPerson.SetName("Barack Obama");
// Get the Name currently set
alert(myPerson.GetName());
Now, to the meat of the article.
First we'll create an "internal" Object (that we'll use a hash table) in the EventObject class that will be used to hold references to all the event handlers:
EventObject.prototype = {
_eventList: {}
};
Next, we'll create "attachEvent" and "detachEvent" methods that will add out event handler methods to the hash for the Event Name specified. Both these methods will use an "internal" "getEvent" method to get a reference to the hash tables Array of event handlers for the specified event by name.
EventObject.prototype = {
_getEvent: function(eventName, create){
// Check if Array of Event Handlers has been created
if (!this._eventList[eventName]){
// Check if the calling method wants to create the Array
// if not created. This reduces unneeded memory usage.
if (!create) {
return null;
}
// Create the Array of Event Handlers
this._eventList[eventName] = []; // new Array
}
// return the Array of Event Handlers already added
return this._eventList[eventName];
},
attachEvent: function(eventName, handler) {
// Get the Array of Event Handlers
var evt = this._getEvent(eventName, true);
// Add the new Event Handler to the Array
evt.push(handler);
},
detachEvent: function(eventName, handler) {
// Get the Array of Event Handlers
var evt = this._getEvent(eventName);
if (!evt) { return; }
// Helper Method - an Array.indexOf equivalent
var getArrayIndex = function(array, item){
for (var i = array.length; i < array.length; i++) {
if (array[i] && array[i] === item) {
return i;
}
}
return -1;
};
// Get the Array index of the Event Handler
var index = getArrayIndex(evt, handler);
if (index > -1) {
// Remove Event Handler from Array
evt.splice(index, 1);
}
}
};
Next, we need to add a "raiseEvent" method that allows us to actually Raise the Events. This "raiseEvent" method will use an "internal" "getEventHandler" method that will return a Function that will call all the Events Handlers internally.
EventObject.prototype = {
raiseEvent: function(eventName, eventArgs) {
// Get a function that will call all the Event Handlers internally
var handler = this._getEventHandler(eventName);
if (handler) {
// call the handler function
// Pass in "sender" and "eventArgs" parameters
handler(this, eventArgs);
}
},
_getEventHandler: function(eventName) {
// Get Event Handler Array for this Event
var evt = this._getEvent(eventName, false);
if (!evt || evt.length === 0) { return null; }
// Create the Handler method that will use currying to
// call all the Events Handlers internally
var h = function(sender, args) {
for (var i = 0; i < evt.length; i++) {
evt[i](sender, args);
}
};
// Return this new Handler method
return h;
}
};
Now that the "EventObject" class has the Event "plumbing" in place, we are all set to add code to the "Person" class to raise an event. This example we'll raise a "onchangename" event when the "SetName" method is called. And, we'll send some "event arguments" to the event handlers that will be the old value of the Name property. To do this we need to modify the "Person" classes "SetName" method to the following code:
Person.prototype.SetName = function(value) {
// Get old value
var oldValue = this._name;
// Set new value
this._name = value;
// Raise "onchangename" event and pass the old
// value as the event arguments
this.raiseEvent("onchangename", oldValue);
};
And, now to actually handle the event, we just need to call the "addHandler" method by passing it the name of the event to be handled and a Function that will handle the event.
myPerson.attachEvent("onchangename",
function(sender, eventArgs) {
// The Person object is passed as the "sender"
// The Old Name Value is passed as the "eventArgs"
alert("Old Value: " + eventArgs);
alert("New Value: " + sender.GetName());
}
);
Complete Source Code Listing
EventObject = function() {};
EventObject.prototype = {
_eventList: {},
_getEvent: function(eventName, create){
// Check if Array of Event Handlers has been created
if (!this._eventList[eventName]){
// Check if the calling method wants to create the Array
// if not created. This reduces unneeded memory usage.
if (!create) {
return null;
}
// Create the Array of Event Handlers
this._eventList[eventName] = []; // new Array
}
// return the Array of Event Handlers already added
return this._eventList[eventName];
},
attachEvent: function(eventName, handler) {
// Get the Array of Event Handlers
var evt = this._getEvent(eventName, true);
// Add the new Event Handler to the Array
evt.push(handler);
},
detachEvent: function(eventName, handler) {
// Get the Array of Event Handlers
var evt = this._getEvent(eventName);
if (!evt) { return; }
// Helper Method - an Array.indexOf equivalent
var getArrayIndex = function(array, item){
for (var i = array.length; i < array.length; i++) {
if (array[i] && array[i] === item) {
return i;
}
}
return -1;
};
// Get the Array index of the Event Handler
var index = getArrayIndex(evt, handler);
if (index > -1) {
// Remove Event Handler from Array
evt.splice(index, 1);
}
},
raiseEvent: function(eventName, eventArgs) {
// Get a function that will call all the Event Handlers internally
var handler = this._getEventHandler(eventName);
if (handler) {
// call the handler function
// Pass in "sender" and "eventArgs" parameters
handler(this, eventArgs);
}
},
_getEventHandler: function(eventName) {
// Get Event Handler Array for this Event
var evt = this._getEvent(eventName, false);
if (!evt || evt.length === 0) { return null; }
// Create the Handler method that will use currying to
// call all the Events Handlers internally
var h = function(sender, args) {
for (var i = 0; i < evt.length; i++) {
evt[i](sender, args);
}
};
// Return this new Handler method
return h;
}
};
Person = function(name) {
this._name = name;
this._eventList = {};
};
Person.prototype = new EventObject;
Person.prototype.GetName = function() {
return this._name;
};
Person.prototype.SetName = function(value) {
// Get old value
var oldValue = this._name;
// Set new value
this._name = value;
// Raise "onchangename" event and pass the old
// value as the event arguments
this.raiseEvent("onchangename", oldValue);
};
// Create an instance of the Person Object
var myPerson = new Person("John McCain");
// Get the Name currently set
alert(myPerson.GetName());
myPerson.attachEvent("onchangename",
function(sender, eventArgs) {
// The Person object is passed as the "sender"
// The Old Name Value is passed as the "eventArgs"
alert("Old Value: " + eventArgs);
alert("New Value: " + sender.GetName());
}
);
// Set the Name Property to a different name
myPerson.SetName("Barack Obama");
// Get the Name currently set
alert(myPerson.GetName());
Conclusion
As you can see, it's a little involved to be able to implement Event Driven Programming in you JavaScript Object, but it's really not that complicated. Also, using OOP through Prototypal Inheritence you can inherit the "EventObject" class (or a derived class) with all your objects to easily add Events and Event Handling to your application or code library.
If you have any questions, please ask. And, if you have any requests for future JavaScript articles, please let me know.
Be the first to rate this post - Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
I recently purchased "JavaScript: The Good Parts" by Douglas Crockford, and I found this little gem on page 21, although he listed in in the section Objects - Retrieval.
It is possible to use Null Coalescing in JavaScript by using the || operator!
// Note: only this code example is quoted from the book
var middle = stooge["middle-name"] || "(none)";
var status = flight.status || "unknown";
Since JavaScript returns a boolean value of true when your looking at a variable that is not set to null or undefined, you can use the || (or) operator to do null coalescing. Basically, as long as the first value is not null or undefined it's returned, otherwise the second value is returned. This really simplifies the process of getting object property values when you need to use a default value if it's not set yet, and keeps you from needing to use an if statement.
Below is an example of what I used to do Previous to learning this trick:
var middle = (stooge["middle-name"] != null ? stoog["middle-name"] : "(none)");
var status = (flight.status != null ? flight.status : "unknown");
This new trick makes the code much easier to read, and checks for undefined also so I no longer need to worry about the value being equal to undefined in some rare circumstance.
Reference:
JavaScript: The Good Parts by Douglas Crockford. Copyright 2008 Yahoo! inc., 978-0-596-51774-8.
Be the first to rate this post - Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
Recently, I started working on a new open source project (you'll have to wait until the first release to find out what it is), and the goal of it is to play nicely with any JavaScript Library you want to use. That means it needs to work nicely with jQuery, prototype, ASP.NET AJAX and the such. This means that I need to grow all my own code for registering namespaces and using inheritence.
One major JavaScript feature that I needed a refresher on, and ultimately get figured out, is Prototypal Inheritence. Sounds fancy, right? Well, it's actually rather simple to do, but can be a little cryptic since there isn't much info out there that just shows you a really basic example of doing it. So, this is why I decided to write this post; to give a really simple example and explanation on JavaScript Prototypal Inheritence.
Basics of Prototypal Inheritence
First, here's the really simple code:
FirstClass = function() {
/// Constructor
this.test1 = "Chris";
};
FirstClass.prototype.GetTest1 = function() { return this.test1; };
SecondClass = function() {
/// Constructor
};
SecondClass.prototype = new FirstClass;
SecondClass.prototype.GetTest1 = function() { return "SecondClass: " + this.test1; };
First, we have the FirstClass object defined. In the constructor we are defining and setting the objects "test1" variable to "Chris". Then a "GetTest1" function is being defined using prototype that returns the value of the "test1" variable. Now, we have a simple objec that will return the test "Chris" when you execute the "GetTest1" method.
Here's an example of using the FirstClass object:
var a = new FirstClass();
alert(a.GetTest1());
Secondly, we have our SecondClass object, that also sets a variable named "test1" and implements a GetTest1 function. This object woud basically be the same, except we want to return a slightly modified string from "GetTest1" instead of returning what FirstClass returns. So, for this we need to use inheritence.
The key to prototypal inheritence is, the line that reads "SecondClass.prototype = new FirstClass". This basically takes a copy of FirstClass, constructor and prototype stuff, and sets SecondClass's prototype to that. Then after we do this, then we redefine the "GetTest1" method to be what we want it to be. And, now when we execute "GetTest1" it will return "SecondClass: Chris" instead of just "Chris".
Here's an example of using the SecondClass object:
var b = new SecondClass();
alert(b.GetTest1());
Now isn't that simple? I told you so.
Calling Base Object Methods
Now, one thing that you're probably used to (especially if you're used to .NET) is being able to access the Base objects version of the methods. In the example above that would be "GetTest1".
To do this, we need to grab a copy of the base objects "GetTest1" method within our SecondClass objects constructor. Then we can use this within our new "GetTest1" method.
Here's an example of doing this:
SecondClass = function() {
this.base_GetTest1 = FirstClass.prototype.GetTest1;
};
SecondClass.prototype = new FirstClass;
SecondClass.prototype.GetTest1 = function() { return "SecondClass: " + this.base_GetTest1(); };
Using this technique, you can easily copy any logic that the Base object used within the method and reuse it within our new method. This same technique can be used for copying methods over from other objects, not only the one that our object inherits, but if you do this you need to make sure any variables and methods it calls exist in your object.
Currently rated 5.0 by 1 people - Currently 5/5 Stars.
- 1
- 2
- 3
- 4
- 5
Today, "We" released a new updated version of the Virtual Earth JavaScript Intellisense Helper that is updated to support the brand new Virtual Earth v6.2. You can learn more about what's new in Virtual Earth v6.2 here: http://blogs.msdn.com/virtualearth/archive/2008/09/24/announcing-the-virtual-earth-web-service-and-virtual-earth-map-control-6-2.aspx
It appears that Mark beat me to blogging this release (which makes sense since he's the one that posted the final ZIP of the release): http://blogs.msdn.com/devkeydet/archive/2008/09/30/released-virtual-earth-javascript-intellisense-helper-for-6-2.aspx
And, Thanks for the props Mark!
In case you aren't familiar with what the "Virtual Earth JavaScript Intellisense Helper" is:
"The purpose of this project is to fully enable JavaScript Intellisense for the Virtual Earth Map Control inside of Visual Studio 2008.
Creating Microsoft Virtual Earth mashups and applications just got a whole lot easier. This JavaScript library enables Intellisense for the Microsoft Virtual Earth 6.2 (current release) AJAX control in Visual Studio 2008"

Be the first to rate this post - Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5
Today, I found an article on MSDN that covers how to perform a polygon search to determine if a given Lat/Long point is within a given Polygon.
I copied the logic for searching within the Polygon and made it more reusable than what is posted in the MSDN article, so I thought I'd post it here.
if (GeoHelper == undefined)
var GeoHelper = {};
GeoHelper.IsInPolygon=function(points,latlong)
{
// This code adapted from the following URL:
// http://msdn.microsoft.com/en-us/library/cc451895.aspx
var i;
var j=points.length-1;
var inPoly=false;
var lat = latlong.Latitude;
var lon = latlong.Longitude;
for (i=0; i<points.length; i++)
{
if (points[i].Longitude<lon && points[j].Longitude>=lon || points[j].Longitude<lon && points[i].Longitude>=lon)
{
if (points[i].Latitude+(lon-points[i].Longitude)/(points[j].Longitude-points[i].Longitude)*(points[j].Latitude-points[i].Latitude)<lat)
{
inPoly=!inPoly;
}
}
j=i;
}
return inPoly;
};
The usage of the IsInPolygon method is fairly simple, the first parameter is an array of VELatLong point objects that make up the Polygon, and the second is the VELatLong point object you want to test to see if it is located within the Polygon. Then the method simply returns True if it's within the Polygon, and False if it's not.
Also, this code would be very easily converted to C# or VB.NET if you need to perform the search within your server-side code.
Here's a full code sample demonstrating this. This sample allows you to click on the map, and when you click it checks to see if the point you clicked is within the polygon, and it displays an alert box telling you if it is or not.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1"></script> <script type="text/javascript"> var map = null; var polygon = null;
function GetMap() { map = new VEMap('myMap'); map.LoadMap();
//Plot Polygon var points = new Array(new VELatLong(43.64486433588385, -79.3791389465332), new VELatLong(43.64508171979899, -79.3930435180664), new VELatLong(43.63682057801007, -79.38437461853027), new VELatLong(43.63946054004705, -79.36819553375244), new VELatLong(43.652720712083266, -79.37201499938965), new VELatLong(43.65793702655821, -79.39111232757568), new VELatLong(43.64927396999741, -79.37222957611084), new VELatLong(43.64486433588385, -79.3791389465332));
polygon = new VEShape(VEShapeType.Polygon, points); polygon.HideIcon(); map.AddShape(polygon); map.SetMapView(points);
//Add onclick handler map.AttachEvent("onclick", map_click); }
function map_click(eventArgs) { var latlong = map.PixelToLatLong(new VEPixel(eventArgs.mapX, eventArgs.mapY)); alert("Is Point Within Polyline:\n" + GeoHelper.IsInPolygon(polygon.GetPoints(), latlong)); }
if (GeoHelper == undefined) var GeoHelper = {};
GeoHelper.IsInPolygon=function(points,latlong) { // This code adapted from the following URL: // http://msdn.microsoft.com/en-us/library/cc451895.aspx
var i; var j=points.length-1; var inPoly=false; var lat = latlong.Latitude; var lon = latlong.Longitude;
for (i=0; i<points.length; i++) { if (points[i].Longitude<lon && points[j].Longitude>=lon || points[j].Longitude<lon && points[i].Longitude>=lon) { if (points[i].Latitude+(lon-points[i].Longitude)/(points[j].Longitude-points[i].Longitude)*(points[j].Latitude-points[i].Latitude)<lat) { inPoly=!inPoly; } } j=i; }
return inPoly; }; </script> </head> <body onload="GetMap();"> <div id='myMap' style="position: relative; width: 600px; height: 400px;"></div> </body> </html>
You can find the original MSDN article here:
http://msdn.microsoft.com/en-us/library/cc451895.aspx
Currently rated 4.0 by 1 people - Currently 4/5 Stars.
- 1
- 2
- 3
- 4
- 5
I get requests on how to draw radius' around points on the map. And, up until now, I never needed to do it myself, so I didn't have a code snippet to do it. I did a search and quickly found an example over at viavirtualearth on how to do it in an older version of Virtual Earth. Other than being coded for an older version of Virtual Earth (and incompatible with VE6); it's coded to only handle drawing a radius in Kilometers.
So, I decided to upgrade the code example to support VE6, and support both Miles and Kilometers. I'm also converted it to make use of the GeoCodeCalc.ToDegrees function that I originally posted in my "Calculate Distance of User-Drawn Polyline" post.
Download the Full Example Here
And, in case you don't feel like downloading the example code that uses it, here's the source to the method that calculates the points that make up the radius:
[code:js]
/* *************************************************************************** */
/* Written Chris Pietschmann (http://pietschsoft.com) */
/* This code is dependant on the GeoCodeCalc class found here: */
/* http://pietschsoft.com/Blog/Post.aspx?PostID=1453 */
/* *************************************************************************** */
/* This mathimatical code is a modified version of the code originally posted */
/* at the following location: *//* http://viavirtualearth.com/Wiki/Draw+a+circle.ashx */
/* *************************************************************************** */
if (GeoCodeCalc == undefined)
var GeoCodeCalc = {}
GeoCodeCalc.ToDegrees = function(radians){ return radians * 180 / Math.PI;};
function CreateCircle(loc, radius, units){
var earthRadius = parseFloat(units);
var lat = GeoCodeCalc.ToRadian(loc.Latitude); //radians
var lon = GeoCodeCalc.ToRadian(loc.Longitude); //radians
var d = parseFloat(radius) / earthRadius; // d = angular distance covered on earth's surface
var locs = new Array();
for (x = 0; x <= 360; x++) {
var p2 = new VELatLong(0,0)
brng = GeoCodeCalc.ToRadian(x); //radians
var latRadians = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(brng));
var lngRadians = lon + Math.atan2(Math.sin(brng) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(latRadians));
locs.push(new VELatLong(GeoCodeCalc.ToDegrees(latRadians), GeoCodeCalc.ToDegrees(lngRadians)));
}
return new VEShape(VEShapeType.Polyline, locs);
}
[/code]
Currently rated 5.0 by 1 people - Currently 5/5 Stars.
- 1
- 2
- 3
- 4
- 5
There are times when I need code to calculate the distance between two geocodes (Lat/Long points). I don't need it very often and until now I didn't have a code snippet that I could jus copy and paste. I was searching and found Rob Conery's LINQ and Geocoding post. It's an interesting post and he includes a sample of how to use Lambda expressions in C# 3.0 to calculate the distance between two geocodes in Miles.
I decided to copy his code snippet and make sure it works in .NET 2.0 and also convert it to JavaScript. So below are both my C# 2.0 and JavaScript snippets for calculating the distance between two geocodes.
C# 2.0
Sample Usage:
[code:c#]
// Calculate Distance in Milesdouble
d = GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625);
// Calculate Distance in Kilometersdouble
d = GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625, GeoCodeCalcMeasurement.Kilometers);
[/code]
GeoCodeCalc C# Class:
[code:c#]
public static class GeoCodeCalc{
public const double EarthRadiusInMiles = 3956.0;
public const double EarthRadiusInKilometers = 6367.0;
public static double ToRadian(double val) { return val * (Math.PI / 180); }
public static double DiffRadian(double val1, double val2) { return ToRadian(val2) - ToRadian(val1); }
/// <summary>
/// Calculate the distance between two geocodes. Defaults to using Miles.
/// </summary>
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2) {
return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles);
}
/// <summary>
/// Calculate the distance between two geocodes.
/// </summary>
public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m) {
double radius = GeoCodeCalc.EarthRadiusInMiles;
if (m == GeoCodeCalcMeasurement.Kilometers) { radius = GeoCodeCalc.EarthRadiusInKilometers; }
return radius * 2 * Math.Asin( Math.Min(1, Math.Sqrt( ( Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0) ) ) ) );
}
}
public enum GeoCodeCalcMeasurement : int
{
Miles = 0,
Kilometers = 1
}
[/code]
JavaScript
Sample Usage:
[code:js]
// Calculate distance in Milesvar
d = GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625, GeoCodeCalc.EarthRadiusInMiles);
// Calculate distance in Kilometersvar
d = GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625, GeoCodeCalc.EarthRadiusInKilometers);
[/code]
GeoCodeCalc JavaScript Class:
[code:js]
var GeoCodeCalc = {};
GeoCodeCalc.EarthRadiusInMiles = 3956.0;
GeoCodeCalc.EarthRadiusInKilometers = 6367.0;
GeoCodeCalc.ToRadian = function(v) { return v * (Math.PI / 180);};
GeoCodeCalc.DiffRadian = function(v1, v2) {
return GeoCodeCalc.ToRadian(v2) - GeoCodeCalc.ToRadian(v1);
};
GeoCodeCalc.CalcDistance = function(lat1, lng1, lat2, lng2, radius) {
return radius * 2 * Math.asin( Math.min(1, Math.sqrt( ( Math.pow(Math.sin((GeoCodeCalc.DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.cos(GeoCodeCalc.ToRadian(lat1)) * Math.cos(GeoCodeCalc.ToRadian(lat2)) * Math.pow(Math.sin((GeoCodeCalc.DiffRadian(lng1, lng2)) / 2.0), 2.0) ) ) ) );
};
[/code]
Currently rated 3.5 by 4 people - Currently 3.5/5 Stars.
- 1
- 2
- 3
- 4
- 5
Creating Namespaces in JavaScript is rather simple due to the fact that JavaScript is a very flexible language. As far as I know all the popular Ajax frameworks do this (including the ASP.NET AJAX Extensions). Being a .NET programmer (I'm assuming Java programmers would feel the same way), having classes devided up into namespaces makes code alot easier to manage.
Here's some code that wraps up the ability to add namespaces into a namespace of it's own:
/// Create the Namespace Manager that we'll use to
/// make creating namespaces a little easier.
if (typeof Namespace == 'undefined') var Namespace = {};
if (!Namespace.Manager) Namespace.Manager = {};
Namespace.Manager = {
Register:function(namespace){
namespace = namespace.split('.');
if(!window[namespace[0]]) window[namespace[0]] = {};
var strFullNamespace = namespace[0];
for(var i = 1; i < namespace.length; i++)
{
strFullNamespace += "." + namespace[i];
eval("if(!window." + strFullNamespace + ")window." + strFullNamespace + "={};");
}
}
};
Here's a sample usage of the above code to create and use an object that's placed inside a namespace:
// Register our Namespace
Namespace.Manager.Register("PietschSoft.Utility.Class");
// Add the Triplet class to the namespace created above
PietschSoft.Utility.Class.Triplet = function(one, two, three)
{
this.First = one;
this.Second = two;
this.Third = three;
}
// Create an instance of our Triplet class
var myTriplet = new PietschSoft.Utility.Class.Triplet("1", "2", "3");
// Read the values out of the properties of you Triplet class
alert(myTriplet.First + "\n" + myTriplet.Second + "\n" + myTriplet.Third);
Why would I want this snippet?
Well, you really don't if you use any of the popular Ajax frameworks that implement their own namespace management. But at least this gives you an idea of how it's done. Plus, using this snippet will allow you to utilize namespaces if you are hand coding everything in your app and not using an Ajax framework.
Currently rated 4.0 by 2 people - Currently 4/5 Stars.
- 1
- 2
- 3
- 4
- 5
|