Thread: Map Logic
View Single Post
  #2 (permalink)  
Old October 8th, 2010, 05:49 PM
flyinhawaiian flyinhawaiian is offline
Friend of Wrox
Points: 539, Level: 8
Points: 539, Level: 8 Points: 539, Level: 8 Points: 539, Level: 8
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2010
Location: Seattle
Posts: 106
Thanks: 1
Thanked 17 Times in 17 Posts
Default

Super frustrating for me too. It took me all afternoon to figure it out.

Code snippet 1-91.txt (for Map.js) appears to be incorrect. The following Map.js is what I got from a finished and working NerdDinner and inserted into my NerdDinner. The main difference I see is the NerdDinner prefix. Be aware there seems to be 3 different finished samples, the original one, MVC2 (the one in the book), and the ever changing one on Codeplex.

I discovered later on, it may not be a good idea to just copy-paste the Codeplex version (below) into your project. Some of the functions expect dinner to have more properties than what is shown in the book. In the event this doesnt work, it may be safer to just add the "NerdDinner" prefix to your existing Map.js instead of replacing the whole thing.

There may be a better way to fix this. But for now, this is it.

Code:
function NerdDinner() { }

NerdDinner.MapDivId = 'theMap';
NerdDinner._map = null;
NerdDinner._points = [];
NerdDinner._shapes = [];

NerdDinner.LoadMap = function (latitude, longitude, onMapLoaded) {
    NerdDinner._map = new VEMap(NerdDinner.MapDivId);

    var options = new VEMapOptions();

    options.EnableBirdseye = false

    // Makes the control bar less obtrusize.
    this._map.SetDashboardSize(VEDashboardSize.Small);

    if (onMapLoaded != null)
        NerdDinner._map.onLoadMap = onMapLoaded;

    if (latitude != null && longitude != null) {
        var center = new VELatLong(latitude, longitude);
    }

    NerdDinner._map.LoadMap(center, null, null, null, null, null, null, options);
}

NerdDinner.ClearMap = function () {
    NerdDinner._map.Clear();
    NerdDinner._points = [];
    NerdDinner._shapes = [];
}

NerdDinner.LoadPin = function (LL, name, description) {
    var shape = new VEShape(VEShapeType.Pushpin, LL);

    //Make a nice Pushpin shape with a title and description
    shape.SetTitle("<span class=\"pinTitle\"> " + escape(name) + "</span>");

    if (description !== undefined) {
        shape.SetDescription("<p class=\"pinDetails\">" + escape(description) + "</p>");
    }

    NerdDinner._map.AddShape(shape);
    NerdDinner._points.push(LL);
    NerdDinner._shapes.push(shape);
}

NerdDinner.FindAddressOnMap = function (where) {
    var numberOfResults = 1;
    var setBestMapView = true;
    var showResults = true;
    var defaultDisambiguation = true;

    NerdDinner._map.Find("", where, null, null, null,
                         numberOfResults, showResults, true, defaultDisambiguation,
                         setBestMapView, NerdDinner._callbackForLocation);
}

NerdDinner._callbackForLocation = function (layer, resultsArray, places, hasMore, VEErrorMessage) {
    NerdDinner.ClearMap();

    if (places == null) {
        NerdDinner._map.ShowMessage(VEErrorMessage);
        return;
    }

    //Make a pushpin for each place we find
    $.each(places, function (i, item) {
        var description = "";
        if (item.Description !== undefined) {
            description = item.Description;
        }
        var LL = new VELatLong(item.LatLong.Latitude,
                        item.LatLong.Longitude);

        NerdDinner.LoadPin(LL, item.Name, description);
    });

    //Make sure all pushpins are visible
    if (NerdDinner._points.length > 1) {
        NerdDinner._map.SetMapView(NerdDinner._points);
    }

    //If we've found exactly one place, that's our address.
    //lat/long precision was getting lost here with toLocaleString, changed to toString
    if (NerdDinner._points.length === 1) {
        $("#Latitude").val(NerdDinner._points[0].Latitude.toString());
        $("#Longitude").val(NerdDinner._points[0].Longitude.toString());
    }
}

NerdDinner.FindDinnersGivenLocation = function (where) {
    NerdDinner._map.Find("", where, null, null, null, null, null, false,
                         null, null, NerdDinner._callbackUpdateMapDinners);
}


NerdDinner.FindMostPopularDinners = function (limit) {
    $.post("/Search/GetMostPopularDinners", { "limit": limit }, NerdDinner._renderDinners, "json");
}

NerdDinner._callbackUpdateMapDinners = function (layer, resultsArray, places, hasMore, VEErrorMessage) {
    var center = NerdDinner._map.GetCenter();

    $.post("/Search/SearchByLocation",
           { latitude: center.Latitude, longitude: center.Longitude },
           NerdDinner._renderDinners,
           "json");
}


NerdDinner._renderDinners = function (dinners) {
    $("#dinnerList").empty();

    NerdDinner.ClearMap();

    $.each(dinners, function (i, dinner) {

        var LL = new VELatLong(dinner.Latitude, dinner.Longitude, 0, null);

        // Add Pin to Map
        NerdDinner.LoadPin(LL, _getDinnerLinkHTML(dinner), _getDinnerDescriptionHTML(dinner));

        //Add a dinner to the <ul> dinnerList on the right
        $('#dinnerList').append($('<li/>')
                        .attr("class", "dinnerItem")
                        .append(_getDinnerLinkHTML(dinner))
                        .append($('<br/>'))
                        .append(_getDinnerDate(dinner, "mmm d"))
                        .append(" with " + _getRSVPMessage(dinner.RSVPCount)));
    });

    // Adjust zoom to display all the pins we just added.
    if (NerdDinner._points.length > 1) {
        NerdDinner._map.SetMapView(NerdDinner._points);
    }

    // Display the event's pin-bubble on hover.
    $(".dinnerItem").each(function (i, dinner) {
        $(dinner).hover(
            function () { NerdDinner._map.ShowInfoBox(NerdDinner._shapes[i]); },
            function () { NerdDinner._map.HideInfoBox(NerdDinner._shapes[i]); }
        );
    });

    function _getDinnerDate(dinner, formatStr) {
        //return '<strong>' + _dateDeserialize(dinner.EventDate).format(formatStr) + '</strong>'; // Codeplex version
        return '<strong>' + _dateDeserialize(dinner.EventDate).toDateString() + '</strong>';
    }

    function _getDinnerLinkHTML(dinner) {
        //return '<a href="' + dinner.Url + '">' + dinner.Title + '</a>';   // Codeplex version has .Url.   The book does not do this.
        return '<a href="' + '/Dinners/Details/' + dinner.DinnerID + '">' + dinner.Title + '</a>';
    }

    function _getDinnerDescriptionHTML(dinner) {
        return '<p>' + _getDinnerDate(dinner, "mmmm d, yyyy") + '</p><p>' + dinner.Description + '</p>' + _getRSVPMessage(dinner.RSVPCount);
    }

    function _dateDeserialize(dateStr) {
        return eval('new' + dateStr.replace(/\//g, ' '));
    }


    function _getRSVPMessage(RSVPCount) {
        var rsvpMessage = "" + RSVPCount + " RSVP";

        if (RSVPCount > 1)
            rsvpMessage += "s";

        return rsvpMessage;
    }
}

NerdDinner.dragShape = null;
NerdDinner.dragPixel = null;

NerdDinner.EnableMapMouseClickCallback = function () {
    NerdDinner._map.AttachEvent("onmousedown", NerdDinner.onMouseDown);
    NerdDinner._map.AttachEvent("onmouseup", NerdDinner.onMouseUp);
    NerdDinner._map.AttachEvent("onmousemove", NerdDinner.onMouseMove);
}

NerdDinner.onMouseDown = function (e) {
    if (e.elementID != null) {
        NerdDinner.dragShape = NerdDinner._map.GetShapeByID(e.elementID);
        return true;
    }
}

NerdDinner.onMouseUp = function (e) {
    if (NerdDinner.dragShape != null) {
        var x = e.mapX;
        var y = e.mapY;
        NerdDinner.dragPixel = new VEPixel(x, y);
        var LatLong = NerdDinner._map.PixelToLatLong(NerdDinner.dragPixel);
        $("#Latitude").val(LatLong.Latitude.toString());
        $("#Longitude").val(LatLong.Longitude.toString());
        NerdDinner.dragShape = null;

        NerdDinner._map.FindLocations(LatLong, NerdDinner.getLocationResults);
    }
}

NerdDinner.onMouseMove = function (e) {
    if (NerdDinner.dragShape != null) {
        var x = e.mapX;
        var y = e.mapY;
        NerdDinner.dragPixel = new VEPixel(x, y);
        var LatLong = NerdDinner._map.PixelToLatLong(NerdDinner.dragPixel);
        NerdDinner.dragShape.SetPoints(LatLong);
        return true;
    }
}

NerdDinner.getLocationResults = function (locations) {
    if (locations) {
        var currentAddress = $("#Dinner_Address").val();
        if (locations[0].Name != currentAddress) {
            var answer = confirm("Bing Maps returned the address '" + locations[0].Name + "' for the pin location. Click 'OK' to use this address for the event, or 'Cancel' to use the current address of '" + currentAddress + "'");
            if (answer) {
                $("#Dinner_Address").val(locations[0].Name);
            }
        }
    }
}

Last edited by flyinhawaiian; October 13th, 2010 at 11:45 AM. Reason: Fixed _getDinnerLinkHTML(dinner) and _getDinnerDate methods in Map.js