Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have a problem with the conversion from pixel to lon/lat. It's not always correct. The map is a simple XYZ map. The items on it are dragable. But after I dragged an item it gives me a wrong lon/lat value. Most of the time it's 50 pixels to low.

I've created a grid on the map with lines every 100 pixels. When I move an item on the 3th line sometimes I get 300, other times 250.

Is this a bug in OpenLayers or is there something I did wrong?

groundplan = new OpenLayers.Layer.XYZ(
    'GroundPlan',
    '@Url.Content("~/Centrals/" + ViewBag.Id)/Maps/' + planId + '/${z}/${x}/${y}.jpg',
    {
        attribution: "© Limotec",
        transitionEffect: 'resize',
        maxExtent: new OpenLayers.Bounds(0, 0, 4096, 4096),
        maxResolution: 4096 / 256,
        numZoomLevels: 5
    }
);
map.addLayer(groundplan);

markers = new OpenLayers.Layer.Vector("Markers",
    {
        renderOptions: { yOrdering: true },
        renderers: renderer
    }
);
map.addLayer(markers);

dragFeature = new OpenLayers.Control.DragFeature(markers);
dragFeature.onComplete = function (feature, pixel) {
    var id = feature.geometry.id;
    id = id.replace('Det_', '');

    //var lonLat = map.getLonLatFromPixel(pixel);
    var lonLat = groundplan.getLonLatFromViewPortPx(pixel);
    console.info("Moved detector " + id + " naar " + lonLat.lon + " - " + lonLat.lat + " (x: " + pixel.x + " y: " + pixel.y + ")");

    $.post('@Url.Action( "MoveDet", "Api" )',
        { "centralId": @ViewBag.Id, "id": id, "lat": lonLat.lon, "lng": lonLat.lat }
    );
}

dragFeature.handlers['drag'].stopDown = false;
dragFeature.handlers['drag'].stopUp = false;
dragFeature.handlers['drag'].stopClick = false;
dragFeature.handlers['feature'].stopDown = false;
dragFeature.handlers['feature'].stopUp = false;
dragFeature.handlers['feature'].stopClick = false; 
map.addControl(dragFeature);
dragFeature.activate();
share|improve this question
add comment

3 Answers

try to use this code for converting pixel to lonlat, I am using too(from GDAL2Tiles ):

var originShift = 2 * MATH.PI * 6378137 / 2.0
var initialResolution = 2 * MATH.PI * 6378137 / 256 // tilesize

function MetersToLatLon( mx, my ){
    //"Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum"

    lon = (mx / originShift) * 180.0
    lat = (my / originShift) * 180.0

    lat = 180 / MATH.PI * (2 * MATH.atan(MATH.exp(lat * MATH.PI / 180.0)) - MATH.PI / 2.0)
    return lat, lon
};

function Resolution(self, zoom ){
    //"Resolution (meters/pixel) for given zoom level (measured at Equator)"

    return self.initialResolution / (2**zoom)
};    

function PixelsToMeters( px, py, zoom){
    //"Converts pixel coordinates in given zoom level of pyramid to EPSG:900913"

    res = Resolution(zoom)
    mx = px * res - originShift
    my = py * res - originShift
    return mx, my
};

now use this method to get right pixeltolonlat:

MetersToLatLon(PixelsToMeters( px, py, zoom));

i hope it helps you...

share|improve this answer
    
It doesn't work. The pixel value is relative to the viewport. It is different when the map is panned. –  Calypoter Jan 4 '13 at 12:56
    
what error did you take when you have executed mentioned method? –  Aragon Jan 4 '13 at 13:03
    
The result is completly wrong. It's negative. The result has to be between 0 and 4096 (the size of the map) –  Calypoter Jan 4 '13 at 13:49
    
My map has no projection. So what I need is the correct possition of the object I moved on the map. From the DragFeature I get the position relative to the viewport. Using map.getLonLatFromPixel gives me sometimes the wrong result because when refreshing the page puts the object on the wrong position. –  Calypoter Jan 8 '13 at 9:19
add comment

In my case, I just needed the right position of first point of a polygon, in pixels. So this is my solution:

  var p = $('path[id^="OpenLayers.Geometry.Polygon"]').attr('d').match(/(\d+\.\d+)\,(\d+\.\d+)/),
  point = new OpenLayers.Pixel(parseInt(p[1]),parseInt(p[2]));

It's just a hack but hope it's helping.

share|improve this answer
add comment
up vote 0 down vote accepted

I've solved my own problem now. Instead of using pixel and calculating the lonlat, I now use feature.geometry to get the correct position. It gives me a better result of the position of the moved object.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.