Developer Notes for Basic ArcXML Overlay Example
|
---------- GENERAL COMMENTS -----------
These notes will only deal with new concepts not covered in previous examples. This has
been done to reduce the repetition that could make working with the notes too difficult.
Refer to previous basic examples if there are areas of this page that you do not understand.
|
---------- NOTE 1 -----------
function onExtentsChangeCB(dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY) {
if (document.form1.checkbox1.checked == true ||
document.form1.checkbox2.checked == true ) {
if (tMapTimer != null){
clearTimeout(tMapTimer);
}
tMapTimer = setTimeout('onMapRedraw()',500); // draw in 1/2 a second
}
}
This function is called whenever the map extents are changed and was set up in the NCSCreateView
class when the view object was instantiated. It checks to see if any of the ArcXML overlay checkboxes
are on and if so, it starts the sequence of events that request a new overlay from the ArcXML server.
It checks to see if the timer is already active (!=null) and if so it clears (stops) the timer. This is
done to deal with the case where the user is in a pan or zoom process and we do not want to generate a
massive number of requests to the GIS server. By clearing the timer and resetting it each time we get
an onExtentsChangeCB event the user must have stopped changing the map extents for 500 mseconds (1/2 second)
before the timer will expire and make the call to the onMapRedraw() function which sets up the request for
a new map from the server.
|
---------- NOTE 2 -----------
function onMouseUpCb(dMask,dScreenX, dScreenY, dWorldX, dWorldY)
{
// Initiated by the mouse up event this callback brings in the following parameters
// dMask - a number which encodes which buttons are depressed on the mouse
// and whether the control key is depressed (see manual for codes)
// dScreenX - the mouse cursor position in screen coordinates (x value)
// dScreenY - the mouse cursor position in screen coordinates (y value)
// dWorldX - the world x coordinate at the mouse cursor
// dWorldY - the world y coordinate at the mouse cursor
if( document && document.ECWView1 ) {
sRGB = document.ECWView1.GetLayerRGB("ArcXMLLayer",dWorldX, dWorldY);
// This code extracts the RGB color value at the
cursor using the .GetLayerRGB() method of the control
// using the world coordinates passed in from the callback
// The following code is used to set individual color transparencies
if( sRGB != "#" ) {
// if no color value is not returned proceed
if( aUserColors[sRGB] == null ) {
// check to see if user has already set trans on this color
// aUserColors is an array set up to hold
the colors that the user has set transparency
// on for this session. This checks that the
user has not already set any transparency
// on this particular color. If they have it
goes below to the else case
if( aStyleColors[sRGB] == null )
// see if this was a style color
// aStyleColors is an array set up to hold
preset color transparencies designed
// to punch out fill colors in the GIS Vector
overlay maps. This checks to see
// if this is a color that has been set and
if not transparency is set to 1.0
// below which is fully opague
dColor = 1.0;
else
// This branch means a style color has been
set to we retrieve it from the array
// and assign it to the dColor variable
dColor = aStyleColors[sRGB];
}
// The branch below indicates that the user
has already set transparency on this color
else
dColor = aUserColors[sRGB];
// pick up the last setting for this color from the array
// cycle through none/all/shaded by
adding .5 to whatever was set before and forcing it back
// to 0.0 when it gets to 1.5
dColor = dColor + 0.5;
if( dColor > 1.0 )
dColor = 0.0;
aUserColors[sRGB] = dColor; // store the new user
set transparency value for that color
// The line above stores the resultant
color back into the array
document.ECWView1.SetLayerTransparency("ArcXMLLayer",
sRGB, aUserColors[sRGB]);
// The line above uses the .SetLayerTransparency()
method of the control to set the
// transparency for that color for the layer named 'ArcXMLLayer'
document.ECWView1.Refresh(); // make sure the view reflects the new value
}
}
}
ANALYSIS:
This function responds to mouse up events which generate a onMouseUp callback which was
defined by this code in the NCSCreateView(). The function is used to set individual color
transparency on a GIS Overlay to 'punch out' fill colors allowing blending with
the underlying raster imagery. The methods shown here only work well with formats like
PNG which have pure colors. Formats like JPEG which use compression need a transparency
mask added to effectively punch out the colors. (refer to manual for information)
|
---------- NOTE 3 -----------
var ArcIMSLayerRailroads, ArcIMSLayerLakes, ArcIMSLayerLand,
ArcIMSLayerNonUSLand, ArcIMSLayerOceans;
ArcIMSLayerRailroads = true;
ArcIMSLayerLakes = true;
ArcIMSLayerLand = true;
ArcIMSLayerNonUSLand = true;
ArcIMSLayerOceans = true;
ANALYSIS:
These variables are used in structuring the request to the ESRI ArcIMS server and
specify which layers should be included in the map file. You will note they are
all set to true for this example. You could modify the page to let the user control
these from checkboxes to set them true or false and the map returned would reflect
the selections.
|
---------- NOTE 4 -----------
function onMapReceived(pName, sURL, pBody, pAction, dWorldTLX,
dWorldTLY, dWorldBRX, dWorldBRY, pResponse) {
ANALYSIS:
This function is called by the onLayerResponse callback when the GIS server has responded.
The first time this function is called, pResponse will have ArcXML code with a url embedded in it
which points to the map image which was generated by the Server. If this url is found then this
function makes another call to retrieve this image. If this retrieves the image it will automatically
be drawn by the control and this function will receive a final message where pResponse = "NCS_OVERLAY_SUCCESS"
Once this is received the function calls onMapRedraw since the user may have zoomed since last map update
to be safe we check to see if the map extents have changed and we need to repeat the map request process.
PARAMETERS:
pName - This specifies the name of the layer which initiated the callback and can be used to test
and branch on for servicing multiple GIS Overlay layers
eg ArcXMLLayer
sURL - Initially this is the url for the ArcXML server. Once a request has been received and the
the image url extracted it becomes the image url on the second request.
pass1 - http://www.geographynetwork.com/servlet/com.esri.esrimap.Esrimap?
ServiceName=Atlas_Railroads&CustomStream=False&Encode=True
pass2 - http://redlands.geographynetwork.com/out/maps/Atlas_Railroads_redmap265835832.png
pBody - This is the arcXML request body that gets sent to the server with instructions for the envelope (bounding box),
image size, type, layers, etc. The server responds with some XML with the image url embedded in it.
pAction - Type of operation which for pass 1 is a POST and for pass 2 is a GET.
The following 4 parameters are world extents that get returned defining the bounding box of the image.
dWorldTLX - example -112.032099 // a geodetic coordinate of upper left corner of map image
dWorldTLY
dWorldBRX
dWorldBRY
pResponse - This returns the XML which the server sends in response to the request for a map image. On pass 1 it
will have the image url embedded (if successful or error message if not) and on pass 2 it will
have 'NCS_OVERLAY_SUCCESS' if successful or an error message if not.
example pass 1 - note the embedded image url="http://redlands.geographynetwork.com/out/maps/Atlas_Railroads_bluemap1550145933.png"
example pass 2 - NCS_OVERLAY_SUCCESS
|
---------- NOTE 5 -----------
if(pResponse == "NCS_OVERLAY_SUCCESS") {
// The control has already had a
valid map back, and drawn it, so do nothing.
document.GIS_Busy.src="images/busy.gif";
} else if(pResponse.substr(0, ("NCS_OVERLAY_FAILURE").length)
== "NCS_OVERLAY_FAILURE") {
alert("Overlay Error\r\nURL: " + sURL + "\r\nBody: " +
pBody + "\r\nResponse: " + pResponse);
document.GIS_Busy.src="images/busy.gif";
ANALYSIS:
If pResponse == "NCS_OVERLAY_SUCCESS" we are on pass 2 of the map request process whereby we have already
extracted the image url retrieved it with a GET call and drawn it into the Layered View. We are
"home and hosed" at this point so we just turn off the server busy animation.
If pResponse is not equal to "NCS_OVERLAY_SUCCESS" we then check for an error condition by looking for
the substring "NCS_OVERLAY_FAILURE" and if found alert the image path, the requesting rbody and the server
response for problem solving purposes. Then we stop the server busy animation.
|
---------- NOTE 6 -----------
else {
if((i = pResponse.indexOf("= 0) {
ANALYSIS:
This code now knows that we are in pass 1 because it failed the two tests described in Note 5 above.
It now tries to determine if there is a valid response by searching for the presence of the substring '
if(sURL == sCurrentMapURL && pBody == pCurrentBody) {
var sParams = "";
sParams = "mode=WORLD;";
sParams += "body=;";
sParams += "action=GET;";
sParams += "worldTLX=" + dWorldTLX + ";";
sParams += "worldTLY=" + dWorldTLY + ";";
sParams += "worldBRX=" + dWorldBRX + ";";
sParams += "worldBRY=" + dWorldBRY + ";";
sParams += "url=" + pImageURL + ";"
document.ECWView1.SetLayerParameter("ArcXMLLayer", sParams);
}
ANALYSIS:
The test ' if(sURL == sCurrentMapURL && pBody == pCurrentBody) { ' is just a validity check that
the server url and request body matches what we stored as we initiated the request.
sParams is structured to do the GET operation through the Control to retrieve the image file. In order
to draw a GIS Overlay type of layer it needs to know the parameters specified.
The .SetLayerParameter() method can be used in the Control to modify the image layer in a number of
different ways including changing transparency etc. You can change the source for the image layer
by specifying "url=imagepath" and this is being used to substitute the new image for the old.
|
---------- NOTE 7 -----------
} else {
// This branch indicates an error condition and the following code alerts the user
document.GIS_Busy.src="images/busy.gif"; // stop the Server Busy indicator
// If its html, open a window, else just pop up an alert
if(pResponse.indexOf("= 0 || pResponse.indexOf(" HTML") >= 0) {
newWin = window.open("", "ErrorWin", "menubar:no,toolbar:no,
resize:no,scrollbars=yes,width=500,height=400");
newWin.document.writeln(" H2> B>Overlay error :");
newWin.document.writeln(" B>URL : ");
newWin.document.writeln(sURL);
newWin.document.writeln(" B>RESPONSE :");
newWin.document.writeln(pResponse);
} else {
alert("Unknown Overlay Response\r\nURL: " + sURL
+ "\r\nBody: " + pBody + "\r\nResponse: " + pResponse);
}
}
ANALYSIS:
This branch indicates that all attempts to handle the request have failed and it is clearly an error
condition. It searches for the substring "" because some servers return an error page and if
so it will display this in a popup window along with the parameters for sURL and pResponse for
error analysis. If not an HTML page it just Alerts the information.
|
---------- NOTE 8 -----------
function onMapRedraw() {
ANALYSIS:
This function is called whenever the extents of the image have been changed, from the onExtentsChangeCB() function
(after a .5 second delay). Also, onMapRedraw sets another timer that calls itself after 5 seconds if no response
has been received from a POST request.
This function checks whether the extents of the map have been changed and does nothing if they have not.
If extents are changed it structures an ArcXML request to the server for a new overlay map image.
|
---------- NOTE 9 -----------
aStyleColors["#FFFFCC"] = 0.0;
aStyleColors["#FFFFFF"] = 0.0;
ANALYSIS:
This array holds transparency values for RGB colors. The aStyleColors[] array is used
to preset values to punch out fill colors as we have done here, setting them to totally transparent
|
---------- NOTE 10 -----------
rbody = ""; ......
This is the body of the request sent to the ArcXML server requesting the map. See note 4 above for discussion.
|
---------- NOTE 11 -----------
document.ECWView1.SetLayerParameter( "ArcXMLLayer", sParams);
ANALYSIS:
This code set the layer's parameters to causes the control to structure an ArcXML request
to the specified url. It then listens for a response and when a response is received,
the onLayerResponse callback is fired which calls the onMapReceived() function
to process the information received from the Server.
|
---------- NOTE 12 -----------
document.ECWView1.SetLayerTransparency( "ArcXMLLayer", "#", TransValue);
ANALYSIS:
The .SetLayerTransparency() method can be used to specify transparency for all the
colors in a layer if the RGB value is designated as just "#". However, any individual
colors that have transparency set will not be effected. You can test this yourself
by bringing in the ESRI GIS overlay and then selecting the pointer mode and changing
the blue ocean color to 50 % transparent. Then change the overlay transparency to 0%
using the text box. You will notice that the blue remains at 50% while the rest of
the image goes fully transparent.
To change the transparency for the overlay image edit the value in the text box and
click outside to effect the change.
|
---------- NOTE 13 -----------
if (document.ECWView1.GetLayerIndex("ArcXMLLayer") == -1) {
if (document.ECWView1.AddLayer("GISOverlay","","ArcXMLLayer","")== 1){
alert("Error adding ArcIMS layer to view : " +
document.ECWView1.GetLastErrorText());
}
}
ANALYSIS:
GetLayerIndex("ArcXMLLayer") == -1 a test to see if this layer exists. If it does
the method will return the layer number and if it does not exist it returns -1
If the layer does not exist it tries to create on with a .AddLayer method. Note that we
specify the layer type as "GISOverlay" as opposed to type "ECW" when we define a layer
for a streaming ECWP image.
The second parameter would normally contain the url for the image file but in this case
it is blank because we are just creating the layer and will load it later in the
onMapReceived() function using a SetLayerParameter() method by specifying "url=imagepath"
If the layer fails to be created then the AddLayer() method returns a -1 rather than the
number for the layer an an error message is displayed by retrieving the error text using
the .GetLastErrorText() method.
|
---------- NOTE 14 -----------
if( document && document.ECWView1 ){ // force an extents callback to update this new map
onExtentsChangeCB(document.ECWView1.GetTopLeftWorldCoordinateX(),
document.ECWView1.GetTopLeftWorldCoordinateY(),
document.ECWView1.GetBottomRightWorldCoordinateX(),
document.ECWView1.GetBottomRightWorldCoordinateY());
}
ANALYSIS:
Normally the onExtentsChangeCB() function is called by an event when the map is panned or zoomed.
In this case we force it in order to get the initial map requested. The Control has a number
of methods that retrieve information about the image and the view and here we use four of
these to extract the world coordinates of the extents of the view window.
|
---------- NOTE 15 -----------
function set_transparency(value) {
var percent = parseFloat(value);
if (percent > 100) percent = 100;
if (percent < 0) percent = 0;
TransValue = percent / 100;
document.ECWView1.SetLayerTransparency( "ArcXMLLayer", "#", TransValue );
document.form1.txtTransparency.value = Math.round(percent) + " %";
}
ANALYSIS:
This function is called when you change the value in the transparency
text box and then click outside the box which fires the onChange event.
The user specifies the transparency in percent which must be converted
to a fraction (100% = no transparency & 0 % = fully transparent)
|
---------- NOTE 16 -----------
NCSCreateView("ECWView1", "100%", "400", PARAM_VIEW_ONLAYERRESPONSE,"onMapReceived();",
PARAM_VIEW_ONPERCENTCOMPLETE, " ECWProgressBar.setProgress(value);",
PARAM_VIEW_ONMOUSEUP,"onMouseUpCb();", PARAM_VIEW_ONEXTENTCHANGE,"onExtentsChangeCB();");
ANALYSIS:
You will notice that three new callbacks have been added compared to the tutorial pages
we have studied before. They are:
PARAM_VIEW_ONLAYERRESPONSE,"onMapReceived();
This callback defines the function to call when the Control has received back the response
from a POST or a GET operation. In this case we end up at the onMapReceived() function
which has been dealt with in depth.
PARAM_VIEW_ONMOUSEUP,"onMouseUpCb();
As discussed above this sets up a callback event when the left mouse is clicked and then
released causing the onMouseUpCB() function to be called. There is a parameter which
changes the Control so that any mouse button will cause a callback event called SetAllMouse.
Refer to your Image Web Server manual for information on using this parameter setting.
PARAM_VIEW_ONEXTENTCHANGE,"onExtentsChangeCB();
This callback has been dealt with at length and is what triggers the sequence of ordering
a new map from the GIS Server(s). As the user pans or zooms this is called many times
since it fires as the extents are changed in real time. A common use of this callback is to display
the extents of the map view to the user on the page for information purposes.
|