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.

  1. 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.

  2. Create an ORDS REST endpoint.
    1. 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;
    2. 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;
    3. Define a template for an endpoint with pattern as ‘vegetation/:z/:x/:y’ on module service1.

      In the p_pattern value used in the following code, vegetation is used to uniquely identify this specific endpoint that accesses the table world. There could be multiple endpoints defined in the model service1 that access the same table. The parameters x, y, and z 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;
    4. Define a handler for the template defined in the preceding step.

      The handler has the same p_module_name and p_pattern as the template. The p_source defines the PL/SQL block that will be executed when the endpoint is accessed. The x, y and z parameters in the p_pattern are passed to the PL/SQL block in p_source, to retrieve a tile from the virtual mosaic created from all the GeoRaster objects in the georaster column of the world 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}

    5. 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.

  3. 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 of XYZ 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.