Microsoft Most Valuable Professional

Chris Pietschmann

An MVP From Wisconsin

ASP.NET AJAX: Create a JavaScript Component with Events

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

Categories: asp.net | JavaScript
Posted by crpietschmann on Friday, November 07, 2008 9:07 PM
Permalink | Comments (0) | Post RSSRSS comment feed


JavaScript: Mixing OOP and Event Driven Programming

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

Categories: JavaScript
Posted by crpietschmann on Tuesday, November 04, 2008 10:53 PM
Permalink | Comments (0) | Post RSSRSS comment feed


JavaScript: Null Coalesce using the || Operator

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

Categories: JavaScript
Posted by crpietschmann on Tuesday, October 14, 2008 9:00 AM
Permalink | Comments (3) | Post RSSRSS comment feed


JavaScript Prototypal Inheritence Explained in Simple Terms

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

Categories: JavaScript
Posted by crpietschmann on Tuesday, September 30, 2008 4:45 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Virtual Earth 6.2 JavaScript Intellisense Helper Released

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

Posted by crpietschmann on Monday, September 29, 2008 8:30 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Virtual Earth: Polygon Search - Is Point Within Polygon?

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

Posted by crpietschmann on Wednesday, July 02, 2008 11:42 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Virtual Earth: Draw a Circle Radius Around a Lat/Long Point

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&#39;s surface
var locs = new Array();
for (x = 0; x &lt;= 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

Posted by crpietschmann on Saturday, February 09, 2008 2:58 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Calculate Distance Between Geocodes in C# and JavaScript

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

Posted by crpietschmann on Friday, February 01, 2008 11:58 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Creating Namespaces in JavaScript is actually rather simple...

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

Categories: JavaScript
Posted by crpietschmann on Tuesday, July 10, 2007 7:31 PM
Permalink | Comments (0) | Post RSSRSS comment feed

About the author

I'm Chris Pietschmann, go to the About Me page to learn more about me.

Search

Sponsors

Web.Maps.VE - ASP.NET AJAX Virtual Earth Mapping Server Control

Recent comments

Disclaimer


This work is licensed under a Creative Commons Attribution 3.0 United States License, unless explicitly stated otherwise within the posted content.
© Copyright 2004 - 2008 Chris Pietschmann