1

Here is the full code (I'll highlight the important parts after):

jQuery(document).ready(function($) {

// =========================================================================================================================================
// -----------------------------------------------------------------------------------------------------------------------------------------
//      DEFINE THE OPENLAYERS MAP
// -----------------------------------------------------------------------------------------------------------------------------------------
// =========================================================================================================================================

    //var pathArray = window.location.href.split( '/' );
    //var base_url = pathArray[0] + '://' + pathArray[2];

    // Base URL (Modified by provisioning script)
    var base_url = 'http://192.168.111.222'

    // Set up URL's
    var arctic_wms = base_url.concat('/geoserver/arctic/wms');
    var arctic_wfs = base_url.concat('/geoserver/arctic/wfs');

    // User the OpenLayers ProxyHost
    OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";

    // Define OpenLayers click Control
    OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {                
                    defaultHandlerOptions: {
                        'single': true,
                        'double': false,
                        'pixelTolerance': 0,
                        'stopSingle': false,
                        'stopDouble': false
                    },

                    initialize: function(options) {
                        this.handlerOptions = OpenLayers.Util.extend(
                            {}, this.defaultHandlerOptions
                        );
                        OpenLayers.Control.prototype.initialize.apply(
                            this, arguments
                        ); 
                        this.handler = new OpenLayers.Handler.Click(
                            this, {
                                'click': this.trigger
                            }, this.handlerOptions
                        );
                    }, 

                    trigger: function(e) {
                        var lonlat = map.getLonLatFromPixel(e.xy);
                        // Create the json_string for frames/get/closest
                        json_string = '{ "type": "Feature", "properties": { "location": "arctic", "x":' + lonlat.lon + ', "y": ' + lonlat.lat + ', "season_names": [ "" ] } }';

                        // Make the ajax call
                        $.ajax({
                            url: base_url.concat('/ops/frames/get/closest'),
                            type: "POST",
                            data: ({app:'rds',data:json_string}),
                            success: function(response){click_alert(response);},
                            error: function(){alert('Error creating popup');}});
                    }
                });

    // DEFINE OpenLayers MAP Options
    var options = {
        maxExtent: new OpenLayers.Bounds(-1500000,-4000000,1500000,0),
        units: 'm',
        projection: "EPSG:3413",

    // Add controls to the map
    controls: [new OpenLayers.Control.Navigation(),
        new OpenLayers.Control.ZoomBox(),
        new OpenLayers.Control.PanZoomBar(),
        new OpenLayers.Control.MousePosition({prefix: '<a target="_blank" ' +'href="http://spatialreference.org/ref/epsg/3413/">' +'EPSG:3413</a>: '}),
        new OpenLayers.Control.ScaleLine(),
        new OpenLayers.Control.LayerSwitcher({'ascending':false})]};

    // DEFINE MAP OBJECT AND POPUP VARIABLE
    var map = new OpenLayers.Map('map',options);

    // ADD AND ACTIVATE CLICK
    var click = new OpenLayers.Control.Click();
    map.addControl(click);
    click.activate();

    // DEFINE WMS LAYERS FOR MAP
    var grn_coast = new OpenLayers.Layer.WMS("Greenland Coastline",arctic_wms,{layers: 'arctic:greenland_coastline'});
    var grn_nat_90 = new OpenLayers.Layer.WMS("Greenland Natural 90m",arctic_wms,{layers: 'arctic:greenland_natural_90m'});
    var grn_bw_45 = new OpenLayers.Layer.WMS("Greenland BW 45m",arctic_wms,{layers: 'arctic:greenland_bw_45m'});
    var rds_fl = new OpenLayers.Layer.WMS("Radar Depth Sounder Flightlines",arctic_wms,{layers: 'arctic:arctic_rds_line_paths',transparent:true,isBaseLayer:false});
    var accum_fl = new OpenLayers.Layer.WMS("Accumulation Radar Flightlines",arctic_wms,{layers: 'arctic:arctic_accum_line_paths',transparent:true,isBaseLayer:false},{visibility:false});
    var snow_fl = new OpenLayers.Layer.WMS("Snow Radar Flightlines",arctic_wms,{layers: 'arctic:arctic_snow_line_paths',transparent:true,isBaseLayer:false},{visibility:false});
    var kuband_fl = new OpenLayers.Layer.WMS("KU Band Radar Flightlines",arctic_wms,{layers: 'arctic:arctic_kuband_line_paths',transparent:true,isBaseLayer:false},{visibility:false});
    var polybound = new OpenLayers.Layer.Vector("Polygon Search Boundary",{'displayInLayerSwitcher':false});
    var selectLine = new OpenLayers.Layer.Vector("Selected Line Vector",{'displayInLayerSwitcher':false});

    // ADD DRAWING CONTROLS TO THE MAP
    drawControls = {polygon: new OpenLayers.Control.DrawFeature(polybound,OpenLayers.Handler.Polygon)};
    for(var key in drawControls) {map.addControl(drawControls[key]);};

    // STORE PROJ4 PROJECTIONS
    var wgs = new Proj4js.Proj('EPSG:4326');
    var ups = new Proj4js.Proj('EPSG:3413');

        // Deactivate drawing on double-click
        drawControls['polygon'].events.register("featureadded",' ',endDraw);
            function endDraw(data){

                // Deactivate
                drawControls['polygon'].deactivate(); 

                // Transform the polygon to WGS84 (EPSG:4326)
                var polybound_wgs  = polybound.features[0].geometry.transform(new OpenLayers.Projection("EPSG:3413"),new OpenLayers.Projection("EPSG:4326"));

                // Get the extent/vertices of the polygon drawn
                var polyExt = polybound_wgs.getBounds();
                var poly = polybound_wgs.getVertices();

                // Set the coordinate boxes to the polygon bounds
                max_lat.value = polyExt.top; min_lat.value = polyExt.bottom; max_lon.value = polyExt.right; min_lon.value = polyExt.left;

            };

        // Clear any polygons on re-activation of draw
        drawControls['polygon'].events.register("activate",' ',clearLayer);
            function clearLayer(data){polybound.removeAllFeatures();};

    // ADD LAYERS TO MAP AND ZOOM TO MAP EXTENT
    map.addLayers([grn_coast,grn_nat_90,grn_bw_45,rds_fl,accum_fl,snow_fl,kuband_fl,polybound,selectLine]);
    map.zoomToMaxExtent();

// =========================================================================================================================================
// -----------------------------------------------------------------------------------------------------------------------------------------
//      TOOLS FOR THE BROWSER
// -----------------------------------------------------------------------------------------------------------------------------------------
// =========================================================================================================================================


$('#draw_bound').click(function() {
    alert("POLYGON DRAWING INSTRUCTIONS:\n\nLeft-Click to add a vertex to your polygon.\nDouble-click to end drawing.");

    // Activate The Polygon Drawing Tool
    drawControls['polygon'].activate();
});

$('#clear_bound').click(function() {
    polybound.removeAllFeatures();
});

$('#clear_coords').click(function() {
    max_lat.value = ""; min_lat.value = ""; max_lon.value = ""; min_lon.value = "";
});

$('#clear_frame').click(function() {
    selectLine.removeAllFeatures();
    if (typeof popup != 'undefined'){map.removePopup(popup);};
});

$('#get_csv').click(function() {

    document.getElementById("status").innerHTML = "<h3>STATUS: GENERATING CSV</h3>";

    // Check if max_lat,min_lat,max_lon,min_lon are empty
    if (max_lat.value == "" || min_lat.value == "" || max_lon.value == "" || min_lon.value == ""){
        alert('Please enter coordinates or "Draw Boundary" to get CSV');document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>";}

    else{

        alert('Your CSV is being generated. A download will pop-up when the file is ready. Make sure your pop-up blocker is disabled.');

        // Construct the bound polygon 'POLYGON((min_lon min_lat,min_lon max_lat,max_lon max_lat,min_lon min_lat,min_lon min_lat))'
        var mla = min_lat.value; var mlo = min_lon.value; var mala = max_lat.value; var malo = max_lon.value;
        var bound_str = ("POLYGON(("+mlo+" "+mla+","+mlo+" "+mala+","+malo+" "+mala+","+malo+" "+mla+","+mlo+" "+mla+"))");

        // Check if polygon string from draw exists (if so overwrite bound_str)
        if (typeof polybound_wgs != 'undefined' && polybound_wgs != ""){bound_str = polybound_wgs;};

        // Construct JSON string
        var json_string = JSON.stringify({'bound':bound_str,location:'arctic'});

        // Call the get csv django view and return the response
        $.ajax({
            url: base_url.concat('/ops/layer_points/get/csv'),
            type: "POST",
            data: ({app:$('#system').val(),data:json_string}),
            success: function(response){csv_alert(response);},
            error: function(){alert('Error creating CSV. Unknown Error.'); document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>";}});
    };
});

function csv_alert(response){
    if (response.status == 0) {alert(response.data); document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>"; return;};
    alert('Your CSV is ready for download, a new window will open. Please save the link, your csv will be available on the server for 7 days.');
    document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>";
    return window.open(response.data,'CSV Download Ready','width=600,height=200');
}

function click_alert(response){

    // Clear the previously selected line
    selectLine.removeAllFeatures();

    // Clear any existing popups
    if (typeof popup != 'undefined'){map.removePopup(popup);};

    // Parse the response from django
    data = jQuery.parseJSON(response.data);

    // Create the vector feature and plot the vector
    var points = new Array();
    for (idx=0;idx<=data.x.length;idx++){
        points.push(new OpenLayers.Geometry.Point(data.x[idx],data.y[idx]))
        };
    var line = new OpenLayers.Geometry.LineString(points);
    var style = {strokeColor: '#FF0000',strokeWidth: 5};
    var linefeature = new OpenLayers.Feature.Vector(line,null,style);
    selectLine.addFeatures([linefeature]);

    // weird thing that makes it work...
    //data = data;

    popup = new OpenLayers.Popup.FramedCloud("Selected Frame", //id
        new OpenLayers.LonLat(data.x[0],data.y[0]), //lonlat
        null, //contentSize
        "<div style='font-size:.8em'>Season: " + data.season_name +"<br>Frame: " + data.frame_name+"</div>", //contentHTML
        null, //closeBox
        true); //closeBoxCallback

    map.addPopup(popup);

    // Check for NO ECHOGRAM ONLINE
    if (data.echogram_url == 'NO ECHOGRAM ONLINE'){alert('No echogram to display in pop-up. Sorry.'); return;};

    // Return a new window with the echogram
    return window.open(data.echogram_url,'Echogram Image');
}

$('#get_kml').click(function() {

    document.getElementById("status").innerHTML = "<h3>STATUS: GENERATING KML</h3>";

    // Check if max_lat,min_lat,max_lon,min_lon are empty
    if (max_lat.value == "" || min_lat.value == "" || max_lon.value == "" || min_lon.value == ""){
        alert('Please enter coordinates or "Draw Boundary" to get KML');document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>";}

    else{

        alert('Your KML is being generated. A download will pop-up when the file is ready. Make sure your pop-up blocker is disabled.');

        // Construct the bound polygon 'POLYGON((min_lon min_lat,min_lon max_lat,max_lon max_lat,min_lon min_lat,min_lon min_lat))'
        var mla = min_lat.value; var mlo = min_lon.value; var mala = max_lat.value; var malo = max_lon.value;
        var bound_str = ("POLYGON(("+mlo+" "+mla+","+mlo+" "+mala+","+malo+" "+mala+","+malo+" "+mla+","+mlo+" "+mla+"))");

        // Check if polygon string from draw exists (if so overwrite bound_str)
        if (typeof polybound_wgs != 'undefined' && polybound_wgs != ""){bound_str = polybound_wgs;};

        // Construct JSON string
        var json_string = JSON.stringify({'bound':bound_str,location:'arctic'});

        // Call the get kml django view and return the response
        $.ajax({
            url: base_url.concat('/ops/layer_points/get/kml'),
            type: "POST",
            data: ({app:$('#system').val(),data:json_string}),
            success: function(response){kml_alert(response);},
            error: function(){alert('Error creating KML. Unknown Error.'); document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>";}});
    };
});

function kml_alert(response){
    if (response.status == 0) {alert(response.data); document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>"; return;};
    alert('Your KML is ready for download, a new window will open. Please save the link, your kml will be available on the server for 7 days.');
    document.getElementById("status").innerHTML = "<h3>STATUS: NORMAL</h3>";
    return window.open(response.data,'KML Download Ready','width=600,height=200');
}

$('#get_mat').click(function() {alert('MAT download in development.');});
$('#max_lat').blur(function() {
    if (max_lat.value > 90){alert("Latitude must be between -90 and 90")};
});

$('#min_lat').blur(function() {
    if (min_lat.value < -90){alert("Latitude must be between -90 and 90")};
});

$('#min_lon').blur(function() {
    if (min_lon.value < -180){alert("Longitude must be between -180 and 180")};
});
$('#max_lon').blur(function() {
    if (max_lon.value > 180){alert("Longitude must be between -180 and 180")};
});
});

So I have a button on an html page that activates the drawing of a polygon on a vector layer. When a feature is added the drawing is halted. When the button to draw is clicked again the features are removed, and the cycle starts over.

Here is the layer:

var polybound = new OpenLayers.Layer.Vector("Polygon Search Boundary" {'displayInLayerSwitcher':false});

Here is adding the drawing controls:

drawControls = {polygon: new OpenLayers.Control.DrawFeature(polybound,OpenLayers.Handler.Polygon)};
for(var key in drawControls) {map.addControl(drawControls[key]);};

Here is the function that activates drawing:

$('#draw_bound').click(function() {
    alert("POLYGON DRAWING INSTRUCTIONS:\n\nLeft-Click to add a vertex to your polygon.\nDouble-click to end drawing.");

    // Activate The Polygon Drawing Tool
    drawControls['polygon'].activate();
});

This clears any existing features on activation:

// Clear any polygons on re-activation of draw
drawControls['polygon'].events.register("activate",' ',clearLayer);
    function clearLayer(data){polybound.removeAllFeatures();};

What happens that I cannot figure out is this:

  1. User clicks the draw button and draws a polygon
  2. User double clicks and drawing is finished, all is well
  3. ERROR HERE: User zooms in/out or unchecks-rechecks the layer in the layer switcher and the polygon they drew disappears. The object still exists, it's just not visible.

Any ideas?

2 Answers 2

1

I ran into a similar problem. Most probably, the problem is the "transform" function that you call here:

// Transform the polygon to WGS84 (EPSG:4326)
var polybound_wgs  = polybound.features[0].geometry.transform(new OpenLayers.Projection("EPSG:3413"),new OpenLayers.Projection("EPSG:4326"));

It not only assigns the transformed geometry to polybound_wgs but it also transforms the original geometry in polybound. So when you zoom out, the feature(s) in polybound get redrawn somewhere else (since the projection has changed from EPSG:3413 to EPSG:4326) OR they do not get rendered at all and are dumped into polybound.unrenderedFeatures.

This is what I did. I cloned the features on polybound layer and then transformed them leaving the original polybound features intact. Alternatively, we can transform the features back to EPSG:4326 when we are done with it (which in this case, will be after assigning the transformed geometry to polybound_wgs)

0

I had a similar issue and found that I needed to add an OpenLayers.Strategy.Refresh strategy to the vector layer, and then call the refresh() method.

I'm not sure why this was necessary as the OpenLayers example doesn't include it. In your case I would make the following changes:

// Define a refresh strategy, make it global so you can call it when needed
var polyboundRefresh = new OpenLayers.Strategy.Refresh({force: true});

// Add the refresh strategy to your layer
var polybound = new OpenLayers.Layer.Vector("Polygon Search Boundary",{
    'displayInLayerSwitcher':false,
    strategies: [ polyboundRefresh ]
});

Now anytime you perform feature operations (add, remove, modify, etc) you can call polyboundRefresh.refresh(); and the layer should refresh. The features should then be persisted across pan, zoom, and visibility events.

1
  • This did not work for me, and I agree it's curious why anything else is needed since the example works as is. I'll continue to try and debug some more. Thanks for your idea. Sep 11, 2013 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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