The first step for developping with the Geoportal API is to download it (See Download). The API project uses Maven for being compiled and installed. Python is also used for Javascript compression, as well as Perl for using a local CGI proxy.
The API must be uncompressed into a web published directory. The layout of the API is as follows :
| trunk | the main directory containing sources, builds, ... the test files are located in the trunk/main/webapp/test directory |
| target | the directory where the API is built. After compilation, it contains the API and the site. The API can be uncompressed when compiling with mvn -Penv-local, compressed when compiling with mvn -Penv-dev |
The directory where the Javascript source codes reside is trunk/main/javascript. This directory is divided into several entries :
| build | This directory contains the ant scripts needed for various operations |
| geoportal | The API source code |
| openlayers | The source code of OpenLayers used by the API |
| proj4js | The source code of PROJ4JS for reprojection handling |
The openlayers and proj4js directories contain the original source codes. Any modifications made on these libraries are located into the geoportal/lib directory :
| Geoportal | Contains the main source codes of the API. The overall structure is the same as OpenLayers. |
| OpenLayers | Contains the OverloadedOpenLayersMinimum.js, OverloadedOpenLayersStandard.js and OverloadedOpenLayersExtended.js files. |
| proj4js | Contains the OverloadedProj4js.js file as well as the catalogues and projCode directories. The former holds a partial EPSG catalogue and the IGNF catalogue. These catalogues describes spatial reference systems used by the API. The latter directory contains new algorithms used in the API whenever necessary. |
The developer can use his/her license key in order to get datasets from the Geoportal. The first step is to tell the API not to load the Geoportal.js compressed code :
<script type="text/javascript" src="http://api.ign.fr/geoportail/api?key=KEY&instance=VIEWER&includeEngine=false&"> <!--//--><![CDATA[//><!-- //--><!]]> </script>
It may be interesting in debug mode to display messages through the use of OpenLayers.Console methods :
<script type="text/javascript" src="../js/VERSION/lib/openlayers/lib/Firebug/firebug.js"> <!--//--><![CDATA[//><!-- //--><!]]> </script>
Then, you have to load your local compressed/uncompressed API. For the uncompressed API, the following code snippet shows how to do it (it is assumed that your web page is located into a directory at the same level as the API is) :
<script type="text/javascript" src="../js/VERSION/lib/geoportal/lib/Geoportal.js"> <!--//--><![CDATA[//><!-- //--><!]]> </script>
the VERSION value is explained in the Integration page.
Your web page can be tested locally. There is no need to run it from the web site declared when obtaining the license key. This insures the developer to code its application locally before deploying it on his/her web site.
The following code shows a complete web page uncompressed_local.html) for local testing :
<!DOCTYPE html>
<html debug="true">
<head>
<title>uncompressed_local.html</title>
<!-- indicates UTF-8 to get proper display of API labels : -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico" />
<!-- include CSS for easying overwriting of styles : -->
<!-- OpenLayers styles : -->
<link id="__OpenLayersCss__" rel="stylesheet" type="text/css" href="../js/VERSION/lib/openlayers/theme/default/style.css"/>
<!--[if lte IE 6]>
<link id="__IE6OpenLayersCss__" rel="stylesheet" type="text/css" href="../js/VERSION/lib/openlayers/theme/default/ie6-style.css"/>
<![endif]-->
<!-- if OpenLayer.Layer.Google is used : -->
<!--
<link id="__GoogleOpenLayersCss__" rel="stylesheet" type="text/css" href="../js/VERSION/lib/openlayers/theme/default/google.css"/>
-->
<!-- if OpenLayers.Popup.FramedCloud is used : -->
<!--
<link id="__FramedCloudOpenLayersCss__" rel="stylesheet" type="text/css" href="../js/VERSION/lib/openlayers/theme/default/framedCloud.css"/>
-->
<link id="__GeoportalCss__" rel="stylesheet" type="text/css" href="../js/VERSION/lib/geoportal/theme/geoportal/style.css"/>
<!--[if lte IE 6]>
<link id="__IE6GeoportalCss__" href="../js/VERSION/lib/geoportal/theme/geoportal/ie6-style.css" type="text/css" rel="stylesheet"/>
<![endif]-->
<!-- if Geoportal.Viewer.Standard is used : -->
<!--
<link id="__StandardCss__" rel="stylesheet" type="text/css" href="../js/VERSION/lib/geoportal/theme/geoportal/standard.css"/>
-->
<style type="text/css"><!--/*--><![CDATA[/*><!--*/
/* overwritten styles or new styles : */
div#footer {
font-size:x-small;
text-align:center;
width:800px;
}
div#footer a, div#footer a:link, div#footer a:visited, div#footer a:hover {
text-decoration:none;
color:black;
}
/*]]>*/--></style>
</head>
<body>
<div id="viewerDiv" style="width:800px;height:600px;"></div> <!-- the map div -->
<div id="footer"><a href="https://api.ign.fr/geoportail/document.do?doc=legal_mentions" target="_blank">Terms of Use</a> - ©IGN 2008-2012</div>
<!-- get the API configuration, but without the API javascript : -->
<script type="text/javascript" src="http://api.ign.fr/geoportail/api?key=YOUR_KEY&includeEngine=false&"><!--//--><![CDATA[//><!--
//--><!]]></script>
<!-- load local Firebug : -->
<script type="text/javascript" src="../js/VERSION/lib/openlayers/lib/Firebug/firebug.js"><!--//--><![CDATA[//><!--
//--><!]]></script>
<!-- load local API : -->
<script type="text/javascript" src="../js/VERSION/lib/geoportal/lib/Geoportal.js"><!--//--><![CDATA[//><!--
//--><!]]></script>
<!-- Application script : -->
<script type="text/javascript"><!--//--><![CDATA[//><!--
var viewer= null; //the viewer instance
if (window.__Geoportal$timer===undefined) {
var __Geoportal$timer= null;
}
// onload event will call myOnLoad :
function myOnLoad() {
if (__Geoportal$timer!=null) {
window.clearTimeout(__Geoportal$timer);
__Geoportal$timer= null;
}
var f;
var C= ['OpenLayers', 'Geoportal', 'Geoportal.Viewer', 'Geoportal.Viewer.Default'];
for (var i= 0, l= C.length; i<l; i++) {
try {
f= eval(C[i]);
} catch (e) {
f= undefined;
}
if (typeof(f)==='undefined') {
__Geoportal$timer= window.setTimeout('myOnLoad();', 300);
return;
}
}
// build a new viewer :
viewer= new Geoportal.Viewer.Default( // Default viewer (one could use Geoportal.Viewer.Standard)
"viewerDiv", // div id where to display dataset
OpenLayers.Util.extend({ // viewer parameters :
//mode:'normal', // default value
//territory:'FXX', // default value
//projection:'IGNF:GEOPORTALFXX', // default value
displayProjection:'IGNF:RGF93G', // default value is 'CRS:84'
//proxy:PROXY+'?url=', // if deemed necessary (KML, etc ... not in the same domain)
nameInstance:'viewer'},
gGEOPORTALRIGHTSMANAGEMENT // API configuration with regard to the API key
)
);
if (!viewer) {
alert('failed loading viewer');
return;
}
viewer.addGeoportalLayers(); // load all available layers
// default center and zoom location :
viewer.getMap().setCenter(viewer.viewerOptions.defaultCenter,viewer.viewerOptions.defaultZoom);
}
window.onload= myOnLoad; // call myOnLoad when onload event is fired
//--><!]]></script>
</body>
</html>The above example can be viewed via http://localhost/YOUR_CONTEXT/uncompress_local.html.
Note : we advise you to use ZazouMiniWebServer as web service (HTTP server) because of its simplicity of use.
The above development model has been designed for people who want to rapidly show maps on the Web. For more advanced usages, the basic API limitations can be ignored by applying the following constructs.
The developer still needs to declare his/her license key, but this time without the VIEWER parameter :
<script
type="text/javascript"
src="http://api.ign.fr/geoportail/api?key=KEY&includeEngine=false&">
<!--//--><![CDATA[//><!-- //--><!]]>
</script>Note : by using the includeEngine parameter set to "false", one asks not to receive the GeoportalMin.js (when VERSION equals "VERSION-m") Geoportal.js or GeoportalExtended.js (when VERSION equals "VERSION-e") Javascript API. This can be usefull for caching such a script.
The API will then sent the following JavaScript content back :
var window.gGEOPORTALRIGHTSMANAGEMENT= {};
gGEOPORTALRIGHTSMANAGEMENT.apiKey= 'KEY';
gGEOPORTALRIGHTSMANAGEMENT['KEY']= {
tokenServer:{url:'TOKEN_SERVER',ttl:TTL},
tokenTimeOut:TTO,
bounds: [MINLON,MINLAT,MAXLON,MAXLAT],
allowedGeoportalLayers:[],
resources:{}
};
gGEOPORTALRIGHTSMANAGEMENT['KEY'].allowedGeoportalLayers.push('LAYER_NAME:SERVICE_TYPE');
gGEOPORTALRIGHTSMANAGEMENT['KEY'].resources['LAYER_NAME:SERVICETYPE']=
{name:'LAYER_NAME',type:'SERVICE_TYPE',url:'http://wxs.ign.fr/geoportail/SERVICE'};
...The content of the global variable gGEOPORTALRIGHTSMANAGEMENT can be now be used for creating the map :
...
my options= OpenLayers.Util.extend(
{
mode:"normal"
},
gGEOPORTALRIGHTSMANAGEMENT
);
...
VIEWER= new Geoportal.Viewer.Default("LocalDiv", options);
...It is now up to the developer to insert this content in his/her application.
One can find templates here :
When the following code is inserted in the web page :
<script
type="text/javascript"
src="http://api.ign.fr/geoportail/api?v=VERSION&key=KEY&instance=VIEWER&">
<!--//--><![CDATA[//><!-- //--><!]]>
</script>the API send back the following Javascript code at the end of the head tag :
var VIEWER= null;
function geoportalLoadVIEWER(idDivMap, mode, territory, crs, dispcrs, proxy){
var options= {};
if(mode) {options.mode= mode;}
if(territory) {options.territory= territory;}
if(crs) {options.projection= crs;}
if(dispcrs) {options.displayProjection= dispcrs;}
if(proxy) {options.proxy= proxy;}
options.nameInstance= 'VIEWER';
options.apiKey= [];
options.apiKey.push('KEY');
options['KEY']= {
tokenServer:{url:'TOKEN_SERVER',ttl:600},
tokenTimeOut:600,
transport:'json',
bounds: [MINLON,MINLAT,MAXLON,MAXLAT],/* the KEY contract extent */
allowedGeoportalLayers:[],
resources:{}
}
/* for each layer in your KEY contract : */
options['KEY'].allowedGeoportalLayers.push('LAYER_NAME:SERVICE_TYPE');
options['KEY'].resources['LAYER_NAME:SERVICE_TYPE']= {
name:'LAYER_NAME',
type:'SERVICE_TYPE',
url:'http://wxs.ign.fr/geoportail/SERVICE'
};
/* end for each */
VIEWER= new Geoportal.Viewer.Default(idDivMap, options);
return VIEWER;
}
// Geoportal API version 1.0 (MODE)
var __Geoportal$listenerLoaded= false;
var __Geoportal$loadComplete= false;
var __Geoportal$onloadCallbacks= null;
var __Geoportal$ready= false;
var __Geoportal$nof= function(){};
var __Geoportal$timer= null;
var __Geoportal$ua= navigator.userAgent.toLowerCase();
var __Geoportal$browser= {" + this.newLine +
version:(__Geoportal$ua.match(/.+(?:rv|it|ra|ie)[\\/: ]([\\d.]+)/) || [0,'0'])[1],
safari:/webkit/.test(__Geoportal$ua) && !/chrome/.test(__Geoportal$ua),
opera:/opera/.test(__Geoportal$ua),
msie:/msie/.test(__Geoportal$ua) && !/opera/.test(__Geoportal$ua),
mozilla:/mozilla/.test(__Geoportal$ua) && !/(compatible|webkit)/.test(__Geoportal$ua),
chrome:/chrome/.test(__Geoportal$ua)
};
function __Geoportal$launch() {
if (__Geoportal$timer!=null) {
window.clearTimeout(__Geoportal$timer);
}
if (viewer==null && typeof(initGeoportalMap)=='function') {
initGeoportalMap();
}
}
function __Geoportal$init() {
__Geoportal$loadListener();
if (!__Geoportal$loadComplete) {
__Geoportal$loadComplete= true;
} else if (!__Geoportal$ready) {
if (__Geoportal$timer!=null) {
window.clearTimeout(__Geoportal$timer);
__Geoportal$timer= null;
}
__Geoportal$ready= (typeof(Geoportal)!=='undefined' && typeof(Geoportal.Viewer)!=='undefined' && typeof(Geoportal.Viewer.Standard)!=='undefined');
if (!__Geoportal$ready) {
__Geoportal$timer= window.setTimeout('__Geoportal$init();',500);
return;
}
if (typeof(__Geoportal$onloadCallbacks)=='function' && __Geoportal$onloadCallbacks!==__Geoportal$nof) {
__Geoportal$onloadCallbacks();
}
__Geoportal$onloadCallbacks= __Geoportal$nof;
if (__Geoportal$onloadCallbacks===__Geoportal$nof) {
__Geoportal$launch();
} else {
__Geoportal$timer= window.setTimeout('__Geoportal$launch();',500);
}
}
}
function __Geoportal$loadListener() {
if (__Geoportal$listenerLoaded) {return;}
__Geoportal$listenerLoaded= true;
/*Mozilla*/
if (document.addEventListener && !/(webkit|opera)/.test(__Geoportal$ua)) {
document.addEventListener("DOMContentLoaded", function() {
document.removeEventListener("DOMContentLoaded", arguments.callee, false);
__Geoportal$init();
}, false);
/*IE*/
} else if (document.attachEvent && !/opera/.test(__Geoportal$ua)) {
if (document.readyState==="complete"){
__Geoportal$init();
} else {
document.attachEvent("onreadystatechange", function() {
if (document.readyState==="complete") {
document.detachEvent("onreadystatechange", arguments.callee);
__Geoportal$init();
}
});
}
if (document.documentElement.doScroll && window==window.top) (function() {
if (__Geoportal$loadComplete) {return;}
try {
document.documentElement.doScroll("left");
} catch (error) {
setTimeout(arguments.callee, 0);
return;
}
__Geoportal$init(); })();
/*Safari, Opera, Chrome*/
} else if (/(webkit|opera)/.test(__Geoportal$ua)) {
var __timer= setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
clearInterval(__timer);
__Geoportal$init();
}
}, 10);
}
if (window.addEventListener) {
window.addEventListener("load", function(e) {
if (window.removeEventListener && e.eventPhase == 3) {
window.removeEventListener("load", arguments.callee, false);
}
__Geoportal$init();
},false);
} else if (window.attachEvent) {
window.attachEvent("onload", function() {
if (window.detachEvent) {
window.detachEvent("onload",arguments.callee);
}
__Geoportal$init();
});
}
}
/* When includeEngine is omitted or true : */
function __Geoportal$onloadcheck() {
if (this.readyState=='loaded' || this.readyState=='complete') {
this.onreadystatechange= null;
this.onload();
this.onload= null;
}
}
/* end of when */
(function() {
__Geoportal$onloadCallbacks= window.onload;
window.onload= __Geoportal$nof;
/* When includeEngine is omitted or true : */
var _sGP= document.createElement('script');
_sGP.type= 'text/javascript';
_sGP.src= "http://api.ign.fr/geoportail/api/js" + VERSION + "GeoportalMODE.js';
_sGP.charset= 'utf-8';
_sGP.onload= __Geoportal$loadListener;
_sGP.onerror= function(){//Useful only on FireFox (to have an error in case of a 404)
throw ('The script ' + this.src + ' has not been found.');
};
if (/msie/.test(__Geoportal$ua) || /webkit/.test(__Geoportal$ua)) {
_sGP.onload= __Geoportal$init;
_sGP.onreadystatechange= __Geoportal$onloadcheck;
}
var nodes= document.getElementsByTagName('head');
var head= nodes.length>0? nodes[0]: document.body;
head.appendChild(_sGP);
/* otherwise */
__Geoportal$loadListener();
/* end when */
})();The minimum API gives the developer the connectors for the WMS-C, WMS and WFS GeoRM protected services. The Geoportal permanent logo is also part of this API (See Terms Of Use). PROJ4JS library is part of this API while OpenLayers is not. The level of API allows web sites with an already existing OpenLayers based viewer to integrate Geoportal services (See the french metadata service web site).
The standard API gives the minimum API features and some feature of OpenLayers (KML, GPX, WMS access, Controls). It also embed a default viewer that was used for previous API releases. There is also another viewer based on the Geoportal web site as an example.
The extended API gives the standard API features and all OpenLayers features.
The mobile API gives access to mobile devices as standard API does.
mvn -e -Penv-local -Dpython_path="python_path\python.exe" \
-Durl_site="api_directory_path\target" \
clean compile site-deployIn order to be able to run current Geoportal API webapp with the next API 2.0 release one has to follow the following steps. More steps will appear on the road to 2.0 release.
The downloading of the API done through the API servlet is deprecated, the 2.0 release will give direct accesses to different flavors and versions of the API. The rational behind this is to simplify and make explicit the API downloading :
<html>
<script type="text/javascript" src="http://api.ign.fr/geoportail/api?v=VERSION&key=CLEF&instance=VIEWER&">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
// the VIEWER variable is declared by the API through the instance parameter
VIEWER= null;
function initGeoportalMap() {
...
geoportalLoadVIEWER("viewerDiv", MODE, TERRITORY, CRS, DISPLAYCRS, PROXY);
...
}
...
//--><!]]></script>
<body>
...
<div id="viewerDiv"></div>
...
</body>
</html>It is then advised to write :
<html>
<!-- SET the includeEngine parameter to false, REMOVE the v parameter : -->
<script type="text/javascript" src="http://api.ign.fr/geoportail/api?key=CLEF&instance=VIEWER&includeEngine=false&">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<!-- DOWNLOAD explicitly the right flavor of the API based on the value of v : -->
<!-- v=VERSION-m -->
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/GeoportalMin.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<!-- v=VERSION : -->
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<!-- v=VERSION-e -->
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/GeoportalExtended.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
// the VIEWER variable is declared by the API through the instance parameter
VIEWER= null;
function initGeoportalMap() {
...
geoportalLoadVIEWER("viewerDiv", MODE, TERRITORY, CRS, DISPLAYCRS, PROXY);
...
}
...
//--><!]]></script>
<body>
...
<div id="viewerDiv"></div>
...
</body>
</html>We will consider now that the API in used in the standard API for the following steps.
The following method for downloading the API's launcher and executing it is deprecated, 2.0 release won't support it anymore. The rational behind this is to let the developer chose his/her strategy to start the API :
<html>
<script type="text/javascript" src="http://api.ign.fr/geoportail/api?key=CLEF&instance=VIEWER&includeEngine=false&">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
// the VIEWER variable is declared by the API through the instance parameter
VIEWER= null;
function initGeoportalMap() {
...
geoportalLoadVIEWER("viewerDiv", MODE, TERRITORY, CRS, DISPLAYCRS, PROXY);
...
}
...
//--><!]]></script>
<body>
...
<div id="viewerDiv"></div>
...
</body>
</html>It is then advised to write :
<html>
<!-- REMOVE the instance and includeEngine parameters : -->
<script type="text/javascript" src="http://api.ign.fr/geoportail/api?key=KEY&">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
// the VIEWER variable is not any more declared by the API
VIEWER= null;
function initGeoportalMap() {
...
geoportalLoadVIEWER("viewerDiv", MODE, TERRITORY, CRS, DISPLAYCRS, PROXY);
...
}
...
//--><!]]></script>
<!-- DEFINE geoportalLoadVIEWER : -->
<script type="text/javascript"><!--//--><![CDATA[//><!--
function geoportalLoadVIEWER(idDivMap, mode, territory, crs, dispcrs, proxy) {
var options= {};
if(mode) {options.mode= mode;}
if(territory) {options.territory= territory;}
if(crs) {options.projection= crs;}
if(dispcrs) {options.displayProjection= dispcrs;}
if(proxy) {options.proxy= proxy;}
options.nameInstance= 'VIEWER';
OpenLayers.Util.extend(options, gGEOPORTALRIGHTSMANAGEMENT || {});
VIEWER= new Geoportal.Viewer.Default(idDivMap, options);
return VIEWER;
}
//--><!]]></script>
<!-- ADD onload callback : -->
<body onload="initGeoportalMap()">
...
<div id="viewerDiv"></div>
...
</body>
</html>One can use window.onload or any other means provided by other frameworks.
The key's information is returned by the API servlet when the key parameter is in use, 2.0 release won't support it anymore. The rational behind this is to allow explicit access to the service in charge of delivering this information :
<html>
<script type="text/javascript" src="http://api.ign.fr/geoportail/api?key=KEY&">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
// the VIEWER variable is not any more declared by the API
VIEWER= null;
function initGeoportalMap() {
...
geoportalLoadVIEWER("viewerDiv", MODE, TERRITORY, CRS, DISPLAYCRS, PROXY);
...
}
...
//--><!]]></script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
function geoportalLoadVIEWER(idDivMap, mode, territory, crs, dispcrs, proxy) {
var options= {};
if(mode) {options.mode= mode;}
if(territory) {options.territory= territory;}
if(crs) {options.projection= crs;}
if(dispcrs) {options.displayProjection= dispcrs;}
if(proxy) {options.proxy= proxy;}
options.nameInstance= 'VIEWER';
OpenLayers.Util.extend(options, gGEOPORTALRIGHTSMANAGEMENT || {});
VIEWER= new Geoportal.Viewer.Default(idDivMap, options);
return VIEWER;
}
//--><!]]></script>
<body onload="initGeoportalMap()">
...
<div id="viewerDiv"></div>
...
</body>
</html>It is advised to write :
<html>
<!-- REMOVE key parameter and therefore the call to the API servlet : -->
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<!-- DEFINE the contracts loader : -->
<script type="text/javascript"><!--//--><![CDATA[//><!--
if (window.__Geoportal$timer===undefined) {
var __Geoportal$timer= null;
}
function checkApiLoading(retryClbk,clss) {
if (__Geoportal$timer!=null) {
//clearTimeout: cancels the timer "__Geoportal$timer" before its end
window.clearTimeout(__Geoportal$timer);
__Geoportal$timer= null;
}
/**
* It may happen that the init function is executed before the API is loaded
* Addition of a timer code that waits 300 ms before running the init function
*/
var f;
for (var i=0, l= clss.length; i<l; i++) {
try {
f= eval(clss[i]);
} catch (e) {
f= undefined;
}
if (typeof(f)==='undefined') {
__Geoportal$timer= window.setTimeout(retryClbk, 300);
return false;
}
}
return true;
}
function loadAPI() {
// wait for all classes to be loaded
if (checkApiLoading(loadAPI,['OpenLayers','Geoportal','Geoportal.Viewer','Geoportal.Viewer.Default'])===false) {
return;
}
// load API keys configuration, then load the interface
Geoportal.GeoRMHandler.getConfig(['KEY'], null, null, {
onContractsComplete: initGeoportalMap
});
}
//--><!]]></script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
// the VIEWER variable is not any more declared by the API
VIEWER= null;
function initGeoportalMap() {
...
geoportalLoadVIEWER("viewerDiv", MODE, TERRITORY, CRS, DISPLAYCRS, PROXY);
...
}
...
//--><!]]></script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
function geoportalLoadVIEWER(idDivMap, mode, territory, crs, dispcrs, proxy) {
var options= {};
if(mode) {options.mode= mode;}
if(territory) {options.territory= territory;}
if(crs) {options.projection= crs;}
if(dispcrs) {options.displayProjection= dispcrs;}
if(proxy) {options.proxy= proxy;}
options.nameInstance= 'VIEWER';
OpenLayers.Util.extend(options, gGEOPORTALRIGHTSMANAGEMENT || {});
VIEWER= new Geoportal.Viewer.Default(idDivMap, options);
return VIEWER;
}
//--><!]]></script>
<!-- CHANGE onload callback : -->
<body onload="loadAPI()">
...
<div id="viewerDiv"></div>
...
</body>
</html>Now, the script is ready for a last improvement : put the scripts at the bottom of the page :
<html>
<head>
<title>...</title>
...
<!-- put CSS here -->
...
</head>
<body>
...
<div id="viewerDiv"></div>
...
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
if (window.__Geoportal$timer===undefined) {
var __Geoportal$timer= null;
}
function checkApiLoading(retryClbk,clss) {
if (__Geoportal$timer!=null) {
//clearTimeout: cancels the timer "__Geoportal$timer" before its end
window.clearTimeout(__Geoportal$timer);
__Geoportal$timer= null;
}
/**
* It may happen that the init function is executed before the API is loaded
* Addition of a timer code that waits 300 ms before running the init function
*/
var f;
for (var i=0, l= clss.length; i<l; i++) {
try {
f= eval(clss[i]);
} catch (e) {
f= undefined;
}
if (typeof(f)==='undefined') {
__Geoportal$timer= window.setTimeout(retryClbk, 300);
return false;
}
}
return true;
}
function loadAPI() {
// wait for all classes to be loaded
if (checkApiLoading(loadAPI,['OpenLayers','Geoportal','Geoportal.Viewer','Geoportal.Viewer.Default'])===false) {
return;
}
// load API keys configuration, then load the interface
Geoportal.GeoRMHandler.getConfig(['KEY'], null, null, {
onContractsComplete: initGeoportalMap
});
}
VIEWER= null;
function initGeoportalMap() {
...
geoportalLoadVIEWER("viewerDiv", MODE, TERRITORY, CRS, DISPLAYCRS, PROXY);
...
}
...
function geoportalLoadVIEWER(idDivMap, mode, territory, crs, dispcrs, proxy) {
var options= {};
if(mode) {options.mode= mode;}
if(territory) {options.territory= territory;}
if(crs) {options.projection= crs;}
if(dispcrs) {options.displayProjection= dispcrs;}
if(proxy) {options.proxy= proxy;}
options.nameInstance= 'VIEWER';
OpenLayers.Util.extend(options, gGEOPORTALRIGHTSMANAGEMENT || {});
VIEWER= new Geoportal.Viewer.Default(idDivMap, options);
return VIEWER;
}
window.onload= loadAPI;
//--><!]]></script>
</body>
</html>Finally, one get ride of geoportalLoadVIEWER() function to directly call the constructor enabling passing more options :
<html>
<head>
<title>...</title>
...
<!-- put CSS here -->
...
</head>
<body>
...
<div id="viewerDiv"></div>
...
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
if (window.__Geoportal$timer===undefined) {
var __Geoportal$timer= null;
}
function checkApiLoading(retryClbk,clss) {
if (__Geoportal$timer!=null) {
//clearTimeout: cancels the timer "__Geoportal$timer" before its end
window.clearTimeout(__Geoportal$timer);
__Geoportal$timer= null;
}
/**
* It may happen that the init function is executed before the API is loaded
* Addition of a timer code that waits 300 ms before running the init function
*/
var f;
for (var i=0, l= clss.length; i<l; i++) {
try {
f= eval(clss[i]);
} catch (e) {
f= undefined;
}
if (typeof(f)==='undefined') {
__Geoportal$timer= window.setTimeout(retryClbk, 300);
return false;
}
}
return true;
}
function loadAPI() {
// wait for all classes to be loaded
if (checkApiLoading(loadAPI,['OpenLayers','Geoportal','Geoportal.Viewer','Geoportal.Viewer.Default'])===false) {
return;
}
// load API keys configuration, then load the interface
Geoportal.GeoRMHandler.getConfig(['KEY'], null, null, {
onContractsComplete: initGeoportalMap
});
}
VIEWER= null;
// REPLACE geoportalLoadVIEWER call :
function initGeoportalMap() {
... /* 1 */
VIEWER= new Geoportal.Viewer.Default(
"viewerDiv",
OpenLayers.Util.extend({
mode:MODE,
territory:TERRITORY,
projection:CRS,
displayProjection:DISPLAYCRS,
proxy:PROXY
}, gGEOPORTALRIGHTSMANAGEMENT || {})
);
... /* 2 */
}
...
window.onload= loadAPI;
//--><!]]></script>
</body>
</html>There is now an interface between various Geoportal's APIs (Javascript, Flash and 3D) whose aim is to allow a unique way for invoking these APIs ... It may be interesting to get prepared to using this interface by modifying the code's skeleton :
The finalized code looks like :
<html>
<head>
<title>...</title>
...
<!-- put CSS here -->
...
</head>
<body>
...
<div id="viewerDiv"></div>
...
<script type="text/javascript" src="http://api.ign.fr/geoportail/api/js/VERSION/Geoportal.js" charset="utf-8">
<!--//--><![CDATA[//><!--
//--><!]]>
</script>
<script type="text/javascript"><!--//--><![CDATA[//><!--
// ADDITION of a variable that will contain the visualisation interface (ease debugging) :
var iVIEWER= null;
// INSERTION of the loader :
function loadAPI() {
// MOVE lines before the call to Geoportal.Viewer.Default :
... /* 1 */
// options are documented in the Geoportal.View.Default constructor :
iVIEWER= new Geoportal.load(
"viewerDiv",
// the key or keys :
['KEY'],
null,
null,
{
mode:MODE,
territory:TERRITORY,
projection:CRS,
displayProjection:DISPLAYCRS,
// WARNING, the option is called proxyUrl and not proxy :
proxyUrl:PROXY,
// KEEP the default viewer :
viewerClass:Geoportal.Viewer.Default,
// CALL initGeoportalMap in order to complete the work :
onView: initGeoportalMap,
// Every layer appearing in the first parameter of addGeoportalLayers() is now there :
layers:[
'LAYER_NAME'
],
// Every options bound to layer appearing in the second parameter of addGeoportalLayers() is now there :
layersOptions:{
'LAYER_NAME':{ ... }
}
}
);
}
// USE OF the interface viewer :
function initGeoportalMap() {
// RETRIEVE the viewer :
var VIEWER= iVIEWER.getViewer();
... /* 2 */
}
...
window.onload= loadAPI;
//--><!]]></script>
</body>
</html>It is recommanded to insert directly the relevant API's CSSes instead of letting the API adds them to the DOM :
<!-- put CSS here --> <!-- import OpenLayers/Geoportal CSS to ease overloading their styles : --> <!-- OpenLayers :--> <link id="__OpenLayersCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/default/style.css" type="text/css" rel="stylesheet"/> <!--[if lte IE 6]> <link id="__IE6OpenLayersCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/default/ie6-style.css" type="text/css" rel="stylesheet"/> <![endif]--> <!-- Geoportal :--> <link id="__GeoportalCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/geoportal/style.css" type="text/css" rel="stylesheet"/> <!--[if lte IE 6]> <link id="__IE6GeoportalCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/geoportal/ie6-style.css" type="text/css" rel="stylesheet"/> <![endif]--> <!-- if Geoportal.Viewer.Standard is in use : --> <link id="__StandardCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/black/standard.css" type="text/css" rel="stylesheet"/> <!-- if Geoportal.Viewer.Mobile is in use --> <link id="__GeoportalMobileCss__" rel="stylesheet" type="text/css" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/mobile/style.css"/> <!-- if black theme is in use : replace the above CSS with those ones --> <link id="__GeoportalBlackCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/black/style.css" type="text/css" rel="stylesheet"/> <!--[if lte IE 6]> <link id="__IE6GeoportalBlackCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/black/ie6-style.css" type="text/css" rel="stylesheet"/> <![endif]--> <!-- if Geoportal.Viewer.Standard is in use : --> <link id="__StandardBlackCss__" href="http://api.ign.fr/geoportail/api/js/VERSION/theme/black/standard.css" type="text/css" rel="stylesheet"/>
Whilst the Geoportal's layer name comprises the ressource name concatenated with the service type (colon separated), a good practice is to avoid using the serviceType in the layer's name to ease to migration. Therefore, it is better to write :
VIEWER.addGeoportalLayers(['LAYER_NAME'],{'LAYER_NAME':{/*properties*/}});than :
VIEWER.addGeoportalLayers(['LAYER_NAME:WMSC'],{'LAYER_NAME:WMSC':{/*properties*/}});This advice also applies when using the layers and layersOptions options of the loader.
The only exception is when using the Minimum API : in that case, the whole identification of the Geoportal's layer is needed.
Usually when defining the territory, one used to set up the default projection explicitly :
VIEWER= new Geoportal.Viewer.Default(
"viewerDiv",
OpenLayers.Util.extend({
mode:MODE,
territory:TERRITORY,
projection:CRS,
displayProjection:DISPLAYCRS,
proxy:PROXY
}, gGEOPORTALRIGHTSMANAGEMENT || {})
);As the default territory's projection changed, it is better not to set up the projection when it is the territory's defaults :
VIEWER= new Geoportal.Viewer.Default(
"viewerDiv",
OpenLayers.Util.extend({
mode:MODE,
territory:TERRITORY,
displayProjection:DISPLAYCRS,
proxy:PROXY
}, gGEOPORTALRIGHTSMANAGEMENT || {})
);Territory's default projections are defined over there. With the upcoming Geoportal, the default projection will be EPSG:3857 for all territories.