Back to <a Berlin Index</a><hr>
<h3>Where we are</h3>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
Since now in this tutorial we've simply examined the external skin of the <b>Rendering Engine</b> implemented by <b>librasterlite2</b> and directly integrated in <b>spatialite_gui</b> via its <b>Map Panel</b>.<br>
It's now time to come down to greater depth so to appreciate all the revolutionary power it can offer.<br><br>
<b>Be prepared for unexpected surprises.</b>

<br><br>
<hr>
<h3>First surprise: Styled Maps can be created by pure SQL statements</h3>
The <b>Rendering Engine</b> (and all that it implies in terms of <b>Styled Map Layers</b>) is fully implemented by <b>librasterlite2</b>, that actually is a <b>dymanic extension</b> expanding the basic SQL capabilities of <b>SQLite</b>.<br>
This practically means that complex and richly styled Maps can be created in the easiest way by just executing some appropriate SQL statement.<br><br>
Such a capability immediately opens the doors for an easy and simple integration of the <b>Rendering Engine</b> in whatever programming language: <b>Java</b>, <b>Python</b>, <b>PHP</b> and many others.<br>
The basic approach will always be exactly the same for all them:
<ol>
<li>Establish a connection to the SQLite database containing the Map by using the appropriate <b>language bindings</b> for your specific language.</li>
<li>Then load both extensions <b>SpatiaLite</b> and
<li>Now you'll be ready for executing any <b>RasterLite2</b> SQL function returning a <b>Styled Map</b><ul>
<li>Each function will then return a <b>BLOB</b> object containing the <b>image</b> corresponding to your request.</li>
<li>At this point your program will simply take some appropriate action (as e.g. displaying the image on the screen) and that's all.</li>

</ol>
Said in other words: developing a feature rich Map Viewer tool will just require to implement the interactive <b>zoom and pan</b> logic.<br>
Any other related task will then directly delegated to the SQL level. Your program will be just required to manage some appropriate <b>SQL query</b>
<ul>
Note that this is an almost universally portable architecture available on practically any of the most common programming languages requiring only few very basic prerequisites:<ul>
<li>Support for some kind of SQLite connector being enabled to dynamically load extension modules.</li>
<li>Installing both <b>SpatiaLite</b> and <b>RasterLite2</b> extensions.</li>

</ul><br>
A practical example based on the <b>OSM Berlin Map</b>
<verbatim>
SELECT RL2_GetImageFromMapConfiguration('osm-berlin',
       BuildMbr(391981.48944364, 5820790.78669314, 392990.18818636, 5821799.48543586, 25833),
       1024, 1024,
       'image/png');
</verbatim>
<ol>
<li>the first argument corresponds to the <b>Map Configuration name</b> (expected to exists into the connected database).</li>
<li>the second argument corresponds to the <b>Bounding Box</b> to be covered by the <b>image</b> to be created.</li>
<li>the third and fourth arguments respectively are the <b>width</b> and <b>heigth</b> (in pixels) pf the image.</li>
<li>and finally the fifth argumets is the <b>MIME type</b> identified the format of the BLOB image to be returned.<br>
The following <b>MIME types</b> are supported:<ul>
TRUE color (RGB) PNG</li>
grayscale or palette based PNG (8 bits X pixel)</li>
GIF</li>
JPEG compressed image</li>
TRUE color (RGB) TIFF</li>
grayscale or palette based TIFF (8 bits X pixel)</li>
TRUE color (RGB) GeoTIFF</li>
grayscale or palette based GeoTIFF (8 bits X pixel)</li>
or PDF document</li>
a flat RGBA matrix of HEIGHT scanlines (from top to bottom)<br>
Each scanline contains WIDTH pixels (from left to right)<br>
Pixels are strictly packed, each one of them requiring 4 bytes. (<b>Red</b>, <b>Green</b>, <b>Blue</b> and <b>Alpha</b> channels).<br>
<b>Note</b>: this specific format usually corresponds to the native one supported by many screen devices.</li>

</ol>
<img alt="blob-img-1" border="1">
<br>This is the PNG image returned by the previous SQL Query as a <b>BLOB</b> object.<br><br>
<hr>
<h3>Second surprise: Styled Maps are always ready to be immediately published as WMS - Web Map Services</h3>
More precisely, it just requires to create an <b>XLM config-file</b> defining the WMS service you intend to publish on the WEB.<br>
Don't worry, it's a very simple step fully supported by a specific <b>GUI Wizard</b><br><br>
<table width="100%" cellspacing="6" cellpadding="6" border="1">
<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
We'll start by opening the Wizard dialog:
<ul>
<li>Press the <b>mouse right button</b> over the <b>root node</b> of the <b>tree view control of all Tables</b><ul>
<li>a <b>context menu</b> will be shown<ul>
<li>now select the menu item shown on the side figure</ul>


</ul>

</td><td width="60%" align="center"><img alt="wms-01">

<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
Fully configuring a WMS Service requires to specify many informations.<br>
If you are in a hurry you can safely leave as they are the meaningles default values.<br><br>
There is nothing critical in the <b>Service Infos</b> tab, so you can directly go to the next tab of the Wizard.

</td><td width="60%" align="center"><img alt="wms-02">

<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
Also in the <b>Contact Infos</b> tab there is nothing interesting, go to the next tab.

</td><td width="60%" align="center"><img alt="wms-03">

<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
Finally in the <b>Miscellaneous Infos</b> tab there there is something interesting.<ul>
<li>We must select sone <b>IP Port number</b> where the <b>WMS Server</b> will listen for incoming requests: <b>8080</b> generally is the optimal choice.</li>
<li>As you can see we've opted for the <b>MiniServer</b> mode.<ul>
<li>This will activate a <b>minimalistic self-contained web server</b> just intended to accept WMS requests coming from the same computer.<br>
It's an absolutely unsafe mode surely causing many potential security issues, but it's completely harmless for internal testing because it denies any access from the external netweork.</li>
<li>The alternative mode is <b>CGI</b>, a robust and very reliable mechanism which however requires the installation of a <b>full feathered WEB Server</b> such as <b>Apache</b>, a not so easy task requiring specific technical skills.</li>
<li><b>Short conclusion</b>: using the <b>MiniServer</b> is the best option for unsofisticated <b>quick and easy</b> testing purposes.<br>
For any serious deployement in a production environmente you absolutely need to use the more professional (and complex) <b>CGI

<li>Last passage: we must now define a <b>Base URL</b> for the <b>WMS Server</b><ul>
<li>You can simply confirm the suggested default that is the most appropriate for the <b>MiniServer

</ul>

</td><td width="60%" align="center"><img alt="wms-04">

<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
You can safely skip the <b>Top Level Layer</b> tab.

</td><td width="60%" align="center"><img alt="wms-05">

<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
Ignore the <b>Legend URL</b> tab and pass to the next and last tab.

</td><td width="60%" align="center"><img alt="wms-06">

<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
The last <b>Advanced Options</b> tab is more or less the same we've already seen in a previous step of this tutoial about <b>Map Global Options</b>, this time intended for the benefit of the <b>WMS Server</b>.<br>
You must specify:<ul>
<li>If enabling or not <b>Multi Threaded Rendering</b>: and if yes, how many parallel threads you intend to authorize.</li>
<li>You must opt between a <b>Transparent</b> or <b>Opaque Background</b>, and in this second case you must select a <b>Background
<li>And finally you can selected the <b>Label Advanced Oprions</b> that you intend to activate.</li>
<li><b>Note</b>: in the specific case of the <b>OSM Berlin Map</b> the <b>Cascaded WMS Options</b> are meaningless simply because in this Map there is no WMS Layer at all.</li>
</ul>

<br>
<table cellspacing="6" cellpadding="6" bgcolor="#f0f0b0"><tr><td>
All right, we've just completed the whole configuration of the <b>WMS Server</b><ul>
<li>press the <b>Export to file</b> button and then save the current configuration somewhere in the file system.</li>
<li>you are now ready to start the <b>WMS Server</b> and begin your practical tests without any further delay</li>
</ul>

</td><td width="60%" align="center"><img alt="wms-07">

<tr><td colspan="2">
<br>
Just for the sake of curiosity, what follows is the <b>XML configuration</b> we've just prepared for publishing the <b>OSM Berlin Map</b> as a <b>Web Map Service</b><br><br>
<table cellspacing="6" cellpadding="6" bgcolor="#ffff00"><tr><td>
<b>Note</b>: this simply is a rather simple <b>text file</b>.
You can arrange it if required by using any <b>text editor</b>: e.g. you could differently arrange the <b>MainDB Path</b> accordingly to the specific publication environment.

<verbatim>
<?xml version="1.0" encoding="UTF-8"?>
<!-- created by spatialite_gui on 2022-06-04 11:08:51 -->
<WmsLiteConfig version="1.0"


  >
	<Service>
		<Name>WMS</Name>
		<Title>WmsLite test server</Title>
		<Abstract>A simple light-weight WMS server for testing RasterLite2 Coverages.</Abstract>
		<KeywordList>
				<Keyword>some keyword</Keyword>
				<Keyword>another keyword</Keyword>
		</KeywordList>

		<ContactInformation>
			<ContactPersonPrimary>
				<ContactPerson>James T. Kirk</ContactPerson>
				<ContactOrganization>United Federation of Planets, Starfleet</ContactOrganization>
			</ContactPersonPrimary>
			<ContactPosition>Starship Captain</ContactPosition>
			<ContactAddress>
				<AddressType>stellar</AddressType>
				<Address>USS Enterprise</Address>
				<City>Planet Earth</City>
				<StateOrProvince>Solar System</StateOrProvince>

				<Country>Milky Way Galaxy</Country>
			</ContactAddress>

		</ContactInformation>
		<Fees>none</Fees>
		<AccessConstraints>none</AccessConstraints>
		<LayerLimit>10</LayerLimit>
		<MaxWidth>5000</MaxWidth>
		<MaxHeight>5000</MaxHeight>
	</Service>
	<GeneralOptions>
		<MultiThreading Enabled="true" MaxThreads="8" />
		<WMS MaxRetries="5" Pause="5" />
		<Background Color="#f2efe9" Transparent="false" />
		<LabelAdvancedOptions AntiCollisionEnabled="true" WrapTextEnabled="true" AutoRotateEnabled="false" ShiftPositionEnabled="false" />
	</GeneralOptions>
	<WmsLayers>
		<TopLevelLayer>
			<Title>Top Level Layer</Title>
		</TopLevelLayer>
		<MainDB
			<Layer Alias="osm-berlin" Name="osm-berlin" Type="MapConfiguration" Child="false" >
				<ChildLayer>forests</ChildLayer>
				<ChildLayer>water_bodies</ChildLayer>
				<ChildLayer>agriculture</ChildLayer>
				<ChildLayer>green_areas</ChildLayer>
				<ChildLayer>buildings</ChildLayer>
				<ChildLayer>religion</ChildLayer>
				<ChildLayer>rivers</ChildLayer>
				<ChildLayer>cemeteries</ChildLayer>
				<ChildLayer>motorway</ChildLayer>
				<ChildLayer>trunk</ChildLayer>
				<ChildLayer>rd_primary</ChildLayer>
				<ChildLayer>rd_secondary</ChildLayer>
				<ChildLayer>rd_tertiary</ChildLayer>
				<ChildLayer>rd_residential</ChildLayer>
				<ChildLayer>paths</ChildLayer>
				<ChildLayer>cycleways</ChildLayer>
				<ChildLayer>subway</ChildLayer>
				<ChildLayer>rail</ChildLayer>
				<ChildLayer>light_rail</ChildLayer>
				<ChildLayer>tram</ChildLayer>
				<ChildLayer>suburbs</ChildLayer>
				<ChildLayer>railway_stations</ChildLayer>
				<ChildLayer>tram_stops</ChildLayer>
			</Layer>
			<Layer Alias="agriculture" Name="agriculture" Type="VectorCoverage" Child="true" />
			<Layer Alias="buildings" Name="buildings" Type="VectorCoverage" Child="true" />
			<Layer Alias="cemeteries" Name="cemeteries" Type="VectorCoverage" Child="true" />
			<Layer Alias="cycleways" Name="cycleways" Type="VectorCoverage" Child="true" />
			<Layer Alias="forests" Name="forests" Type="VectorCoverage" Child="true" />
			<Layer Alias="green_areas" Name="green_areas" Type="VectorCoverage" Child="true" />
			<Layer Alias="light_rail" Name="light_rail" Type="VectorCoverage" Child="true" />
			<Layer Alias="motorway" Name="motorway" Type="VectorCoverage" Child="true" />
			<Layer Alias="paths" Name="paths" Type="VectorCoverage" Child="true" />
			<Layer Alias="rail" Name="rail" Type="VectorCoverage" Child="true" />
			<Layer Alias="railway_stations" Name="railway_stations" Type="VectorCoverage" Child="true" />
			<Layer Alias="rd_primary" Name="rd_primary" Type="VectorCoverage" Child="true" />
			<Layer Alias="rd_residential" Name="rd_residential" Type="VectorCoverage" Child="true" />
			<Layer Alias="rd_secondary" Name="rd_secondary" Type="VectorCoverage" Child="true" />
			<Layer Alias="rd_tertiary" Name="rd_tertiary" Type="VectorCoverage" Child="true" />
			<Layer Alias="religion" Name="religion" Type="VectorCoverage" Child="true" />
			<Layer Alias="rivers" Name="rivers" Type="VectorCoverage" Child="true" />
			<Layer Alias="suburbs" Name="suburbs" Type="VectorCoverage" Child="true" />
			<Layer Alias="subway" Name="subway" Type="VectorCoverage" Child="true" />
			<Layer Alias="tram" Name="tram" Type="VectorCoverage" Child="true" />
			<Layer Alias="tram_stops" Name="tram_stops" Type="VectorCoverage" Child="true" />
			<Layer Alias="trunk" Name="trunk" Type="VectorCoverage" Child="true" />
			<Layer Alias="water_bodies" Name="water_bodies" Type="VectorCoverage" Child="true" />
		</MainDB>
	</WmsLayers>
</WmsLiteConfig>
</verbatim>

</table>
<br><hr>
<h3>Ready to go: starting and testing the WMS MiniServer</h3>
<table width="100%" cellspacing="6" cellpadding="6" border="1">
<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
<ol>
<li>Start a <b>command shell</b> window.<br>
On MS Windows it's <b>cmd.exe</b>, the infamous <b>black window</b> hated and feared by so many average users.</li>
<li>Then launch in execution <b>wmslite</b> by specifying the appropriate invocation arguments.<ul>
<li><b>wmslite</b> is one of the standard tools that are usually distributed together with

<li>on success a wellcome message will be printed on the screen so to confirm that <b>wmslite</b> is ready to accept incoming WMS requests.</li>
</ol>

<br>
<table cellspacing="6" cellpadding="6" bgcolor="#f0f0b0"><tr><td>
<b>Warning</b>: the <b>black window / command shell</b> is the WMS MiniServer itself !!!<br>
Never close it prematurely because such an action will immediately terminate the WMS Server.<br>
You are warned.

<br>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
<h3>command syntax</h3>
<verbatim>
wmslite -svr -cf .\osm-berlin-wms.xml -p 8080
</verbatim>
<ul>
<li><b>-svr</b> activates the <b>MiniServer
<li><b>-cf specifies the absolute or relative pathname of the <b>XML configuration
<li><b>-p 8080</b> specifies the number of the <b>IP Port</b> to be listened by the MiniServer for accepting incoming requests</li>
</ul>

<br>
For more detailed informations about all the invocation arguments supported by <b>wmslite</b>:
<verbatim>
wmslite --help
</verbatim>
</td><td width="60%" align="center"><img alt="wms-08">

<tr><td>
<table cellspacing="6" cellpadding="6" bgcolor="#b0f0b0"><tr><td>
<h3>Testing the WMS Server</h3>
<ul>
<li>you can test the WMS Server using <b>QGIS</b> (or <b>spatialite_gui</b>, or any other GIS supporting WMS)</li>
<li>if you are in a hurry the quickest and simplest ways is just by <b>copying & pasting</b> the following <b>request URL</b> into your <b>Web Browser</b><br>
<verbatim>

&REQUEST=GetMap&VERSION=1.3.0&LAYERS=osm-berlin&CRS=EPSG:25833
&BBOX=372900.376996,5808182.301315,406414.329857,5826524.528562
&WIDTH=1723&HEIGHT=943&STYLES=&FORMAT=image/png&TRANSPARENT=TRUE&BGCOLOR=0xFFFFFF
</verbatim><ul>
<li>as shown by the side figure a <b>WMS Map</b> will quickly be displayed on the Web Browser window.</li>

</ul>

</td><td width="60%" align="center"><img alt="wms-09">

</table>

<br><hr><br>
Back to <a Berlin Index</a><br><br>