[GIS] OpenLayers Point Feature Vanish on Zoom-In

openlayers-2point

I use OpenLayers to animate a point moving along a line. To do this I use several map layers and one vector layer to contain one LineString feature and one Point feature. Currently, the animation is working but I have one issue where every time I zoom in the map, the Point feature vanish even though the LineString is still shown. When I zoom out, the Point feature is shown again but when I try to zoom in again, the Point vanished.

These are screenshots of what happen
Default Zoom
Try to zoom in, point vanished
Zoom out again, point returns

This is a portion of source code I use to animate the Point:

/* == Fitur Simulasi Gerak di Rute */
var themarker = new OpenLayers.Feature.Vector(
    new OpenLayers.Geometry.Point(map.getCenter().lon, map.getCenter().lat),
    null,
    {externalGraphic: imgUrl+"symbol/perusak kawal.png", pointRadius: 10, rotation: -90}
);
var linePath;
var indexPoint = 0;
var bergeraklah = function() {
    var pindah = function(dari, ke, asal) {
        var jumlah = 10; // hardcoded
        var xmove = Math.abs(asal.x - ke.x)/jumlah;
        var ymove = Math.abs(asal.y - ke.y)/jumlah;
        // x-axis
        if (dari.x < ke.x) {
            if (dari.x + xmove < ke.x) {
                dari.x += xmove;
            } else {
                dari.x = ke.x;
            }
        } else {
            if (dari.x - xmove > ke.x) {
                dari.x -= xmove;
            } else {
                dari.x = ke.x;
            }
        }
        // y-axis
        if (dari.y < ke.y) {
            if (dari.y + ymove < ke.y) {
                dari.y += ymove;
            } else {
                dari.y = ke.y;
            }
        } else {
            if (dari.y - ymove > ke.y) {
                dari.y -= ymove;
            } else {
                dari.y = ke.y;
            }
        }
    };

    var interval = 100; // hardcoded
    if (themarker.isMoving) {
        var tujuan = linePath.geometry.components[indexPoint];
        if (themarker.geometry.x != tujuan.x || themarker.geometry.y != tujuan.y) {
            pindah(themarker.geometry, tujuan, linePath.geometry.components[indexPoint-1]);
            g.ruteLayer.drawFeature(themarker);
            window.setTimeout(bergeraklah, interval);
        } else {
            themarker.isMoving = false;
            bergeraklah();
        }
    } else if (indexPoint < (linePath.geometry.components.length-1)) {
        var prev = linePath.geometry.components[indexPoint];
        // fetch next point
        var tujuan = linePath.geometry.components[++indexPoint];
        // hitung kemiringan
        var bearing = tc1(prev.x, prev.y, tujuan.x, tujuan.y);
        themarker.isMoving = true;
        themarker.style.rotation = bearing - 90; // gambarnya hadap kanan 90 derajat
        pindah(themarker.geometry, tujuan, linePath.geometry.components[indexPoint-1]);
        g.ruteLayer.drawFeature(themarker);
        window.setTimeout(bergeraklah, interval);
    } else {
        // selesai
        g.simulating = false;
        g.ruteLayer.removeFeatures([themarker]);
    }
};


$('#button-simulasi').bind('click', function(e) {
    if (!g.simulating) {
        g.simulating = true;
        indexPoint = 0;
        linePath = g.ruteVector.clone();
        themarker.geometry.x = linePath.geometry.components[0].x;
        themarker.geometry.y = linePath.geometry.components[0].y;
        g.ruteLayer.addFeatures([themarker]);
        themarker.isMoving = false;
        bergeraklah();
    }
});
/* == End of Fitur Simulasi Gerak di Rute */

Does anybody know what cause the vanishing Point? Because I tried to google it but still don't find any solution.

Best Answer

Okay, I accidentally found the solution. I need to call method calculateBounds() on every OpenLayers.Geometry object every time I move that object.

Apparently every geometry object in OpenLayers has some kind of bounds which determine whether that object should be drawn or not. So, when moving a geometry object, I have to refresh those bounds. And apparently calling OpenLayers.Layer.Vector::redraw or OpenLayers.Layer.Vector::drawFeature didn't recalculate those bounds automatically.

Now I modify the code above to include recalculating bounds before redrawing

...
pindah(themarker.geometry, tujuan, linePath.geometry.components[indexPoint-1]);
themarker.geometry.calculateBounds();
g.ruteLayer.drawFeature(themarker);
...

And now the Point Feature never vanish unintentionally again.