C.1 Example 1: A Raster Tile Service Using ORDS With a Single Raster Layer
This example assumes that the raster data is stored in a table
called world
under schema scott
. The table
world
is defined with the following structure:
CREATE TABLE world (
georid NUMBER PRIMARY KEY,
georaster SDO_GEORASTER
);
The table world
contains six rows and each
GeoRaster object in the georaster
column is a georeferenced
3 band raster with SRID 8307, with a cell depth of 8BIT_U and the spatial
extent of the virtual mosaic is WGS84 (-180 -90 180 90).
Perform the following steps to create an endpoint that calls the SDO_GEOR_UTL.get_rasterTile function and configure a raster tile layer on MapLibre. Ensure to replace any default values as needed for your environment.
- Configure ORDS.
Use the command ords install (see Installing and Configuring Oracle REST Data Services) to create a new connection to ORDS by specifying the database connection parameters.
- Create an ORDS REST endpoint.
- Use the following PL/SQL block to REST-enable schema
scott
:BEGIN ORDS.ENABLE_SCHEMA( p_enabled => TRUE, p_schema => 'SCOTT', p_url_mapping_type => 'BASE_PATH', p_url_mapping_pattern => 'scott', p_auto_rest_auth => FALSE); COMMIT; END;
- Use the following PL/SQL block to define a module named
service1
:BEGIN ORDS.DEFINE_MODULE( p_module_name => 'service1', p_base_path => '/service1/', p_items_per_page => 25, p_status => 'PUBLISHED', p_comments => NULL); COMMIT; END;
- Define a template for an endpoint with pattern as
‘vegetation/:z/:x/:y’
on moduleservice1
.In the
p_pattern
value used in the following code,vegetation
is used to uniquely identify this specific endpoint that accesses the tableworld
. There could be multiple endpoints defined in the modelservice1
that access the same table. The parametersx
,y
, andz
are the parameters passed in through the endpoint URL string. They will be passed to the SDO_GEOR_UTL.get_rasterTile function in the next step.BEGIN ORDS.DEFINE_TEMPLATE( p_module_name => 'service1', p_pattern => 'vegetation/:z/:x/:y', p_priority => 0, p_etag_type => 'HASH', p_etag_query => NULL, p_comments => NULL); COMMIT; END;
- Define a handler for the template defined in the preceding
step.
The handler has the same
p_module_name
andp_pattern
as the template. Thep_source
defines the PL/SQL block that will be executed when the endpoint is accessed. Thex
,y
andz
parameters in thep_pattern
are passed to the PL/SQL block inp_source
, to retrieve a tile from the virtual mosaic created from all the GeoRaster objects in thegeoraster
column of theworld
table.BEGIN ORDS.DEFINE_HANDLER( p_module_name => 'service1', p_pattern => 'vegetation/:z/:x/:y', p_method => 'GET', p_source_type => ords.source_type_media, p_items_per_page => 0, p_mimes_allowed => '', p_comments => NULL, p_mle_env_name => NULL, p_source => 'SELECT ''image/png'' as mediatype, SDO_GEOR_UTL.GET_RASTERTILE( TABLE_NAME=>''WORLD'', GEOR_COL_NAME=> ''GEORASTER'', TILE_X=>:x, TILE_Y=>:y, TILE_ZOOM=>:z, MOSAIC_PARAM=>''resFilter=false'') from dual' ); COMMIT; END;
The raster tile service is now ready to receive HTTP requests with the pattern:
http://localhost:8080/ords/scott/service1/vegetation/{z}/{x}/{y}
- Verify the endpoint by sending a GET request using curl or
a web browser to the URL
http://localhost:8080/ords/scott/service1/vegetation/0/0/0
.{z}
,{x}
, and{y}
in the URL pattern (shown in the previous step) are replaced by zeros to request the unique tile at zoom level zero.
- Use the following PL/SQL block to REST-enable schema
- Consume the endpoint using MapLibre.
The following HTML and JavaScript code shows how to add the raster tile service endpoint created at Step 2 to MapLibre GL (Graphics Library) JS (Java Script).
The relevant elements of the example code are:
- The
‘type’
attribute in a source object with value‘raster’
and‘tiles’
attribute with value array ofXYZ
endpoint URLs. - The
‘type’
attribute in a layer object with value‘raster’
and attribute‘source’
that references the source object.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Display GeoRaster</title> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script> <link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet" /> <style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; } </style> </head> <body> <div id="map"></div> <script> const map = new maplibregl.Map({ container: 'map', style: 'https://maps.oracle.com/mapviewer/pvt/res/style/osm-positron/style.json', center: [0.0, 0.0], zoom: 1, transformRequest: (url, resourceType) => { if (resourceType === 'Tile' && ( url.startsWith('https://maps.oracle.com/mapviewer/pvt') || url.startsWith('https://elocation.oracle.com/mapviewer/pvt')) ){ return { url: url, headers: {'x-oracle-pvtile': 'OracleSpatial'}, credentials: 'include' }; } } }); const sourceId = 'raster-tiles'; map.on('load', function () { map.addSource(sourceId, { 'type': 'raster', 'tiles' : ['http://localhost:8080/ords/scott/service1/vegetation/{z}/{x}/{y}'], 'minzoom': 0, 'maxzoom': 22, 'tileSize' : 256 }); map.addLayer( { 'id': 'georaster', 'type': 'raster', 'source': sourceId, 'paint': { 'raster-opacity': 1, 'raster-hue-rotate': 0, 'raster-brightness-min': 0, 'raster-brightness-max': 1, 'raster-saturation': 0, 'raster-contrast': 0, 'raster-fade-duration': 300 } } ); }); map.addControl(new maplibregl.NavigationControl()); map.addControl(new maplibregl.FullscreenControl()); </script> </body> </html>
Note that you can customize the preceding example according to your requirements.
- The