Question

I have the following code which will update a textbox with latitude / longitude of a location when I drag a marker on the map to its location:

var listener = function (evt) {
    /* We check if this drag listener is called while the marker is being
        * dragged using the default behavior component
        */
    var mapDragType = evt.dataTransfer.getData("application/map-drag-type");

    if (mapDragType === "marker") {
        // Get the marker itself.
        var marker = evt.dataTransfer.getData("application/map-drag-object");

        // Get the offset of the mouse relative to the top-left corner of the marker.
        var offset = evt.dataTransfer.getData("application/map-drag-object-offset");

        /* Calculate the current coordinate of the marker, so substract the offset from the 
            * current displayX/Y position to get the top-left position of the marker and then
            * add the anchor to get the pixel position of the anchor of the marker and then 
            * query for the coordinate of that pixel position
            */
        var coordinate = map.pixelToGeo(evt.displayX - offset.x + marker.anchor.x, evt.displayY - offset.y + marker.anchor.y);

        // If the marker is dragged above a zone where it may not be dropped
        if (evt.dataTransfer.dropEffect === "none") {
            // If this is the end of the drag
            if (evt.type === "dragend") {
                // then the marker will jump back to where it was; 
                updateInputValue(marker, marker.coordinate.toString());
            }
            else {
                // otherwise it is currently (while being dragged) above an invalid drop zone
                updateInputValue(marker, "Invalid drop zone!");
            }
        }
        else {
            // If the marker is somewhere above the map, update info text with the new coordinate.
                updateInputValue(marker, coordinate.toString());
        }
    }
};

/* Create a helper method that updates the text fields associated with the 
    * marker passed as argument
    */
var updateInputValue = function (draggedMarker, text) {
    if (draggedMarker === marker)
        $("input[name*='txtGeoLocation']").val(text);
    //markerPosUiElt.innerHTML = text;
};

The problem I'm having is that the latitude / longitude outputs in long format when I need it in decimal format.

I've tried changing the following lines:

updateInputValue(marker, marker.coordinate.toString());

To the following:

updateInputValue(marker, marker.coordinate.latitude.ToString() + ', ' + marker.coordinate.longitude.ToString());

But then my text box stops populating (I imagine an error is throwing which isn't bubbling up). I've even tried just retrieving the latitude with the following:

updateInputValue(marker, marker.coordinate.latitude.ToString());

But I still receive no output.

How can I accomplish this? I definitely don't want a long format latitude / longitude and only wish to write the decimal version on this to my textbox.

Was it helpful?

Solution

The coordinate of a marker is only updated during the dragend event, so if you want to track the intermediate locations, you'll have to a re-calculate the current target location during the drag event using the map.pixelToGeo() method. You can reference the moving marker as the target of the current event i.e. evt.target

  • The evt.target.coordinate of the Marker i.e. the coordinate property returns a formatted latitude/longitude.
  • The evt.target.coordinate.latitude and evt.target.coordinate.longitude give the coordinates in decimal degrees.

Here is a working example - you'll need to substitute in your own app id and token to get it to work of course.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9; IE=EmulateIE10;"/>
        <base href="http://developer.here.com/apiexplorer/examples/api-for-js/events/map-object-events-displayed.html" />
        <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
        <title>Nokia Maps API for JavaScript Example: Map Object events</title>
        <meta name="description" content="Adding event listeners to objects on the map"/>
        <meta name="keywords" content="mapobjectevents, map, display, object, events"/>
        <!-- For scaling content for mobile devices, setting the viewport to the width of the device-->
        <meta name=viewport content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>

        <!-- By default we add ?with=all to load every package available, it's better to change this parameter to your use case. Options ?with=maps|positioning|places|placesdata|directions|datarendering|all -->
        <script type="text/javascript" charset="UTF-8" src="http://api.maps.nokia.com/2.2.4/jsl.js?with=all"></script>


    </head>
    <body>
        <div id="mapContainer" style="width:70%; height:70%; left:0; top:50; position: absolute;"></div>
        <div id="uiContainer" style="left:0; top:0; position: absolute;" >HELLO</div>
        <script type="text/javascript" id="exampleJsSource">
// <![CDATA[    
/////////////////////////////////////////////////////////////////////////////////////
// Don't forget to set your API credentials
//
// Replace with your appId and token which you can obtain when you 
// register on http://api.developer.nokia.com/ 
//
            nokia.Settings.set( "appId", "YOUR APP ID GOES HERE"); 
            nokia.Settings.set( "authenticationToken", "YOUR AUTHENTICATION TOKEN GOES HERE");

/////////////////////////////////////////////////////////////////////////////////////   

// Get the DOM node to which we will append the map
var mapContainer = document.getElementById("mapContainer");
// Create a map inside the map container DOM node
var map = new nokia.maps.map.Display(mapContainer, {
    // Initial center and zoom level of the map
    center: [52.51, 13.4],
    zoomLevel: 7,
    // We add the behavior component to allow panning / zooming of the map
    components:[new nokia.maps.map.component.Behavior()]
});



// Create a default listener for events that will just log a message.
var defaultHandler = function (evt) {

    if (evt.target instanceof nokia.maps.map.Marker) {

        //console.log(evt);

        var div = document.getElementById("uiContainer");
        if (evt.type = "dragend"){
            div.innerHTML = evt.type + " Formated: " + evt.target.coordinate  + " Decimal: " + evt.target.coordinate.latitude + ", " + evt.target.coordinate.longitude;
        }
        if (evt.type = "drag"){
            var coordinate = map.pixelToGeo(evt.displayX + evt.target.anchor.x, evt.displayY + evt.target.anchor.y);
            div.innerHTML = evt.type + " Formated: " + coordinate  + " Decimal: " + coordinate.latitude + ", " + coordinate.longitude;
        }
    }

    if (evt.target instanceof nokia.maps.map.Spatial) {
        /* Prevent other event listeners from being triggered
         * For more details see  nokia.maps.dom.Event
         */
        evt.stopImmediatePropagation();
    }
};

/* Adding event listeners one by one to a map object is not very
 * efficient therefore we have created a shortcut method 
 * to add multiple eventlisteners to an object using the "eventListener" property
 */

// Template with all listeners to be registered.
var listeners = {
    // type: [(listener, useCapture, namespaceURI)(, listener, useCapture, namespaceURI)(, ...)]
    "dragstart": [defaultHandler, false, null],
    "drag": [defaultHandler, false, null],
    "dragend": [defaultHandler, false, null]
}; 

// Create image marker object
var imageMarker = new nokia.maps.map.Marker(
    [52.88745, 13.43246],
    {
        $name: "Image Marker",
        eventListener: listeners,
        icon: "../../res/markerHouse.png",
        anchor: new nokia.maps.util.Point(35, 89),
        draggable: true
    }
);

// Add event listeners to the marker
imageMarker.addListeners(listeners);
map.objects.add(imageMarker);


// ]]>
        </script>
    </body>
</html>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top