Hello!
This is something that has been bothering me for a few months. I had a temporary solution but it is time to optimize the speed of our mapping application, so I want to see if you guys can help with a better solution.
Here is the situation:
I have a map which uses Callback Requests to change stuff on the back end. But after the Callback Request returns, and I call the OpenLayers API redraw( ) method, it doesn't work.
My dilemma is that if I call Generate_Map( ), it works. But this is a VERY SIMPLIFIED example. I have about 20 other layers on my map, and Generate_Map( ) has to reload all of them. Is there a way to do something the way Refresh_Map( ) works. It seems like it is just ignoring me every time I tell it to Redraw( ).
public partial class __Default : System.Web.UI.Page, ICallbackEventHandler
{
Map tgMap; //This is only here for the sample code... In reality this is defined in the ASPX file...
Dictionary<string, string> zipTerritory = new Dictionary<string, string>( );
protected void Page_Load( object sender, EventArgs ea )
{
if ( !IsPostBack )
{
ZipTerritory_Load( );
Generate_Map( );
}
}
protected void ZipTerritory_Load( )
{
SqlDataReader sqlDataReader = new SqlDataReader( );
/*
...
Some code has been removed for brevity where sqlDataReader" is loaded with data!
...
*/
zipTerritory.Clear( );
while ( sqlDataReader.Read( ) )
{
zipTerritory[sqlDataReader["Zip"].ToString( )] = sqlDataReader["Color"].ToString( );
}
}
protected void Generate_Map( )
{
ShapeFileFeatureLayer zipShape = new ShapeFileFeatureLayer( /* ... Omitted ... */ );
zipShape.FeatureSource.CustomColumnFetch += new EventHandler<CustomColumnFetchEventArgs>( Zip_CustomColumnFetch );
ValueStyle zipTerritoryColor = new ValueStyle( "TerritoryId", new Collection<ValueItem>( ) );
zipTerritoryColor.ValueItems.Add( new ValueItem( "1", new AreaStyle( new GeoSolidBrush( GeoColor.StandardColors.Red ) ) ) );
zipTerritoryColor.ValueItems.Add( new ValueItem( "2", new AreaStyle( new GeoSolidBrush( GeoColor.StandardColors.Red ) ) ) );
zipTerritoryColor.ValueItems.Add( new ValueItem( "3", new AreaStyle( new GeoSolidBrush( GeoColor.StandardColors.Red ) ) ) );
zipShape.ZoomLevelSet.ZoomLevel01.CustomStyles.Add( zipTerritoryColor );
zipShape.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
LayerOverlay mainOverlay = new LayerOverlay( "Main", true, TileType.MultipleTile );
mainOverlay.Layers.Add( "Zip", zipShape );
tgMap.CustomOverlays.Clear( );
tgMap.CustomOverlays.Add( mainOverlay );
}
protected void Zip_CustomColumnFetch( object sender, CustomColumnFetchEventArgs ea )
{
FeatureSource zipShape = (FeatureSource) sender;
Feature zipFeature = zipShape.GetFeatureById( ea.Id, ReturningColumnsType.AllColumns );
string zipCode = zipFeature.ColumnValues["ZIP"];
if ( ea.ColumnName.StartsWith( "TerritoryId" ) )
{
ea.ColumnValue = zipTerritory[zipCode];
}
}
private string callbackResult = "";
public string GetCallbackResult( )
{
return callbackResult;
}
public void RaiseCallbackEvent( string callbackRequestString )
{
string[] data = callbackRequestString.Split( new char[] { '|' } );
string zipCode = data[0];
string territoryId = data[1];
zipTerritory[zipCode] = territoryId;
SqlCommand cmd = new SqlCommand( /* ... */ );
cmd.Execute( string.Format( "UPDATE SET territoryId = {0} WHERE zip = {1}", territoryId, zip ) ); //SIMPLIFIED EXAMPLE
Generate_Map( ); // THIS WORKS, but I am starting from SCRATCH. SUB-OPTIMAL.
/*
But would prefer to do to this:
*/
Refresh_Map( ); // Would prefer to simply NUDGE the server to refresh only what I need
}
public void Refresh_Map( )
{
LayerOverlay layerOverlay = (LayerOverlay) tgMap.CustomOverlays["Main"];
ShapeFileFeatureLayer layer = (ShapeFileFeatureLayer) layerOverlay.Layers["Zip"];
layerOverlay.Redraw( ); // DOES NOT WORK
layer.FeatureSource.GeoCache.Clear( ); // DOES NOT WORK
}
}
function LayerRedraw( name, callback )
{
var l = OpenLayersMap.getLayer( name );
if ( l )
{
if ( l.mergeNewParams )
{
l.mergeNewParams( { 'version' : Math.random( ) } );
}
l.redraw( );
}
}