After I read some questions at the mapbuilder phorum, regarding the GetFeatureInfo functionality, I think that many mapbuilder developers will appreaciate some hints, how to
customize the output from the GetFeatureInfo WMS service. So this tutorial will guide you through these topics...
- How to attach your own XSLT template to the FeatureInfo widget.
- I will describe exactly the way, how the GetFeatureInfo requests are being composed and dispatched to the mapbuilder server.
- We will look closer at the WidgetBaseXSL.paint method.
Globally, I think you will agree with me, that the mapbuilder demo applications are sufficient only if you want to be familiar with the basic mapbuilder principles. But sooner or later you
will realize, especially in the case of the semantic data output format (WMS GetFeatureInfo), that you need to implement other capabilities. This web page you can consider as
the short tutorial to how and especially where, you can „hack" mapbuilder in the GetFeatureInfo functional area.
a) How to attach your own XSLT template to the FeatureInfo widget.
In the case of the FeatureInfo widget, FeatureInfo.xsl template is being taken by default. If you want to set your own template, you have to define stylesheet tag
as the child element of the FeatureInfo element in the config.xml. Previously mentioned application logic is being performed via this source code, located at the beginning of
the WidgetBaseXSL.js code:
For some reasons, if you are uncomfortable with this application logic, you can change it here. But be aware! WidgetBaseXSL is the predecesor of all mapbuilder widgets,
so if you want to make a code change just for FeatureInfo widget, you have to distinguish, if you are currently holding the FeatureInfo widget instance or another one. For this
purpose check the widgetNode parameter (attribute nodeName)
b) Displaying of the GetFeatureInfo results.
Semantic-data retrieving process begins with the mouse click in the map container. Mapbuilder then asks all WMS layers, which has queryable parameter set to „1", what elements are
being situated at the selected position. It's good to know, that mapbuilder client sends WMS GetFeatureInfo request for every queryable layer!! Result, from every GetFeatureInfo
request, is then being appended in the web page, behind the previous one. Needless to say, that this is unwanted behaviour, if you want to have just one HTML output with one
operating element (like combobox), which would be responsible for which one of the returned result will be displayed*.* (one important note: you will never
encounter this problem if you have just one queryable layer!!... Ok, so lets take a look, what you have to do, to change this workflow. First off all, why new FeatureInfo
result is being appending behind the previous one ??? Answer is hidden in the WidgetBaseXSL.js code in the paint method.
Worthless to say, that, for 'FeatureInfo' widget, you must only change the marked row, with your code, depending on your desired HTML output. For example I had to add
newly returned featureType names into my already appended operating element (HTML combobox). Default calling of the appenChild method, resulted in the situation that I
had more then one operating elements in my web page instead of one, with all founded feature type names.....my part of the code here is:
document variable contains link to your current WEB page. You can access here previously appended FeatureInfo result.
tempNode.document variable contains link to the HTML document, which is going to be appended into the Web page.
c) Modification of the GetFeatureInfo request.
If you need to modify the way, how the GetFeatureInfo requests are being dispatched from the client side, best place to do that is GetFeatureInfo.js code. Especially look at
the doAction method, which is being performed, after the click in the map container. Code part, which deserve your attention, is especially the for cycle, which loops
through all queryable, non-hidden layers (listed in the context document) and sends the appropriate GetFeatureInfo requests.
I am sure, that you are courious about, from where exactly mapbuilder sends GetFeatureInfo requests and where mapbuilder receives the results. These steps are being performed
in the ModelBase.js source code, exactly in the loadModelDoc method. For example, you can modify here the properties of the XMLHttpRequest object, like i did. For example
I wanted to send all GetFeatureInfo requests synchronizedly instead of asynchronizedly, like it was being performed by default, you can cache here the
GetFeatureInfo result into the memory...and so on...It's up to you....
d) ProxyRedirect Servlet (ProxyRedirect.java):
If you will take a look closely at the ModelBase.loadModelDoc method, you should notice, that GetFeatureInfo requests are being sent through the proxy servlet named
ProxyRedirect. URL looks like proxy?url=<GetFeatureInfo request>. Coming through the proxy is necessary due to the security restriction of the XMLHttpRequest
object.Unfortunatelly proxyRedirect servlet contains some issues, Here is the list of the problems, discovered and fixed by myself:
- ProxyRedirect servlet was not forwarding http url headers to the target WMS server. (problems with the basic user authentication).
- ProxyRedirect servlet was not handling JSESSIONID handshake, if your WMS server resides at the J2EE Oracle Application Server for example.. (This was causing that every WMS request, dispatched through the proxy server, created new session at the J2EE application server).