4.5 Using Dynamic Tile Layers

A dynamic tile layer is a tile layer defined on the client side.

A dynamic tile layer differs from a regular tile layer in the following ways:

  • It is defined by the client application, so it does not need to be predefined in the USER_SDO_CACHED_MAPS metadata.

  • The server does not cache the map tiles.

  • It can use third party maps services, when a map tile image URL generation function is provided.

Thus, a dynamic tile layer can be defined dynamically by a client application, and the map images may come from a map visualization component server or from a third party map service.

4.5.1 Creating a Universe and Configuration Instance for a Dynamic Tile Layer

Before creating a dynamic tile layer instance, you must create a universe and a tile layer configuration for a dynamic tile layer.

For example, assume that a variable named baseURL is properly defined (such as http://myapp.mycorp.com/mapviewer) and that the specified data source exists. You must create a tile layer configuration instance and a universe instance. You can use an Oracle Maps JavaScript API built-in universe or create your own. For simplicity, a built-in universe is used here.

A tile layer configuration instance only needs to define the dimension of an image tile, and 256 pixels for a tile image's width and height are commonly used. The following code snippet creates this instance:

  var  myuniv= new OM.universe.LatLonUniverse();  // a built-in universe
  var  myconfig=new OM.layer.TileLayerConfig(  // a tile layer configure instance
          {
	        tileImageWidth: 256,  
	        tileImageHeight: 256
          });

4.5.2 Creating a Dynamic Tile Layer Using a Base Map

Creating a dynamic tile layer using a base map is the simplest approach, because the map contents are already defined by a server-side map visualization component base map. Follow these steps.

  1. Create a ServerMapRequest instance and set its properties. For example:

            var req = new OM.server.ServerMapRequest(baseURL);
            req.setProperties({
                dataSource:"MVDEMO",
                basemap: 'demo_map',  // this basemap property defines the map contents
                transparent:true,
                antialiase:"false"
            });
    
  2. Create an object containing properties of this dynamic tile layer. For example:

            var dtl_props = {  
                universe: myuniv,            
                tileLayerConfig: myconfig,
                tileServerURL: baseURL + "/omserver",  // map images come from this omserver
                enableUTFGrid: true,  // the UTFGrid is enabled
                enableUTFGridInfoWindow: true,  // the info window for displaying UTFGrid is enabled
                utfGridResolution: 4   // one grid cell represents 16 (4 by 4) image pixels
            };
    

    In this example, the string value in variable tileServerURL is pointing to a map visualization component server. It could be the same server as where the web application is deployed, or another map visualization component server instance. For example, it can be in either of the following forms:

    • From the same Oracle Maps server instance:. For example:

      var baseURL=document.location.protocol+"//"+document.location.host+"/mapviewer";
    • From another Oracle Maps server instance. For example:

      var baseURL="http://myapp.mycorp.com/mapviewer ";
  3. Create a dynamic tile layer. For example:

      var dynamic_tilelayer_1 = new OM.layer.DynamicTileLayer("dtl1", dtl_props, req);

    The dynamic tile layer requests map images from the map visualization component's map server (omserver), which renders a fresh map image and does not cache the images on disk.

From the preceding examples, notice that three statements are given to create a dynamic tile layer: (1) create a map request instance (ServerMapRequest); (2) create an object containing the dynamic tile layer related properties; and (3) instantiate a dynamic tile layer.

The dynamic tile layer requests map images from the map visualization component's map server (omserver), which renders a fresh map image and does not cache the images on disk.

4.5.3 Creating a Dynamic Tile Layer Using Predefined Themes

Another approach to creating a dynamic tile layer is to use predefined themes. Follow these steps.

  1. Create a ServerMapRequest instance and set its properties. For example:

            var req = new OM.server.ServerMapRequest(baseURL);
            req.setProperties({
                dataSource:"MVDEMO",
                transparent:true,
                antialiase:"false",
            });
            // the three themes below are defined in the metadata already.
            var t1 = new OM.server.ServerPredefinedTheme("THEME_DEMO_STATES");
            var t2 = new OM.server.ServerPredefinedTheme("THEME_DEMO_HIGHWAYS");
            var t3 = new OM.server.ServerPredefinedTheme("THEME_DEMO_CITIES");
            req.addThemes([t1, t2, t3]);
    
  2. Create an object containing properties of this dynamic tile layer. For example:

            var dtl_props = {  
                universe: myuniv,            
                tileLayerConfig: myconfig,
                tileServerURL: baseURL + "/omserver",
                enableUTFGrid: true,
                enableUTFGridInfoWindow: true,
                utfGridResolution: 4
            };
    
  3. Create a dynamic tile layer. For example:

      var dynamic_tilelayer_2 = new OM.layer.DynamicTileLayer("dtl2", dtl_props, req);

    The dynamic tile layer requests map images from the map visualization component's map server (omserver), which renders a fresh map image and does not cache the images on disk.

Instead of specifying a server base map, in this approach the ServerMapRequest instance adds some map visualization component server predefined themes. From a practical perspective, this allows the client-side application to create tile layers using the server-side defined themes in the view USER_SDO_THEMES.

4.5.4 Creating a Dynamic Tile Layer Using Spatial Tables Directly

You can directly use spatial tables for a dynamic tile layer by creating ServerJBCTheme instances and adding them into a ServerMapRequest instance. Follow these steps.

  1. Create a style. For example:

            var myc1 = new OM.style.Color({
                styleName: "mycolor1",
                stroke: "#333333", 
                strokeOpacity: 1.0,
                fill: "#F2EFE9", 
                fillOpacity: 1.0
            });
    
  2. Create a JDBC theme and set its properties. Spatial tables are used in a SQL query statement. The statement, as a string type variable, is set as an attribute in the OM.server.ServerJDBCTheme instance. For example:

            var jdbcTStates= new OM.server.ServerJDBCTheme('theme_jdbc_states');
            jdbcTStates.setDataSourceName('mvdemo');
            jdbcTStates.setSRID('8307');
            jdbcTStates.setGeometryColumnName('geom');
            var sql='select totpop, poppsqmi, state, state_abrv, geom from states'; // the query
            jdbcTStates.setQuery(sql);  // set the SQL string
            jdbcTStates.addInfoColumn({column: 'state_abrv', name:'State'});
            jdbcTStates.addInfoColumn({column: 'totpop', name:'Population'});
            jdbcTStates.addInfoColumn({column: 'poppsqmi', name:'Pop. Density'});
            jdbcTStates.setRenderingStyleName('mycolor1');
    
  3. Create a ServerMapRequest instance and set its properties. For example:

            var req = new OM.server.ServerMapRequest(baseURL);
            req.setProperties({
                dataSource:"MVDEMO",
                transparent:true,
                antialiase:"false",
            });
            req.addTheme(jdbcTStates);
            req.addStyle(myc1);
    
  4. Create an object containing properties of this dynamic tile layer. For example:

            var dtl_props = {  
                universe: myuniv,            
                tileLayerConfig: myconfig,
                tileServerURL: baseURL + "/omserver",
                enableUTFGrid: true,
                enableUTFGridInfoWindow: true,
                utfGridResolution: 4
            };
    
  5. Create a dynamic tile layer. For example:

      var dynamic_tilelayer_3 = new OM.layer.DynamicTileLayer("dtl3", dtl_props, req);

In this example, a dynamically defined style and a ServerJDBCTheme object are created first. The ServerJDBCTheme can make use the spatial tables directly using a SQL statement. The tables are then used by the addTheme and addStyle methods of a ServerMapRequest object.

4.5.5 Creating a Dynamic Tile Layer Using Third Party Map Services

Another approach to create a dynamic tile layer is to use third party map services. The map service URL of a third party is provided by a client provided URL generation function. Follow these steps.

  1. Using the third party map service provider's specifications, create a URL construction function for building map image requests by a dynamic tile layer. For example:

    var urlb = function (w, h, minX, minY, maxX, maxY, options){
          var str="http://my.mycorp.com:8080/geoserver/ows?";
          var optParams="";
          str = str+"request=getmap"+
          "&bbox="+minX+","+minY+","+maxX+","+maxY+
          "&width="+w+
          "&height="+h;
          
        if (!OM.isNull(options)) {
          for (var key in options) {
            optParams=optParams +"&"+key +"="+options[key];
          }
        }    
        return str+optParams;
      }
    
  2. Create an object containing properties of this dynamic tile layer. For example:

    var dtl_props = {  
        universe: myuniv,            
        tileLayerConfig: myconfig,
        urlBuilder: urlb,
        urlBuilderOptions: {
                  "layers":  "topp:states,sf:sfdem,sf:roads,sf:streams",
                  "CRS":     "CRS:84",
                  "service": "WMS",
                  "version": "1.3.0",
                  "format":  "image/png"
            } 
    };
    
  3. Create a dynamic tile layer. For example:

      var dynamic_tilelayer_4 = new OM.layer.DynamicTileLayer("dl4", dtl_props);

In this example, a dynamic tile layer instance (dynamic_tilelayer_4) contains a urlBuilder property to provide a URL generation function (iurlb). The URL generation function will be used by the dynamic tile layer for fetching image tiles from the specified map service provider. This example uses a third party map provider, a GeoServer instance, to provide map images.

Additional map service provider required parameters can be provided in the urlBuilderOptions property. This example specifies several additional parameters (layers, CRS, service, version, and format) needed by the GeoServer instance.

4.5.6 Dynamic Tile Layer Use Case

This topic describes a dynamic tile layer use case.

The code examples come from a dynamic tile layer application. The application uses the map visualization component server to provide map image tiles. It uses spatial tables directly via an OM.server.ServerJDBCTheme instance.

  1. Obtain the SQL query's "where" clause from an application's user interface using the getWhereClauseFromUI() function, assuming that this function is properly defined already in that application and returns expected results. For example:

        var  wherec = getWhereClauseFromUI();
  2. Create a JDBC theme and set its properties. For example:

        var objJDBCTheme= new OM.server.ServerJDBCTheme();
        objJDBCTheme.setDataSourceName('storm');
        objJDBCTheme.setSRID('3857');
        objJDBCTheme.setXColumnName('long_loc');
        objJDBCTheme.setYColumnName('lat_loc');
    
        objJDBCTheme.addInfoColumn({column: 'YEAR', name:'Year'});
        objJDBCTheme.addInfoColumn({column: 'MONTH', name:'Month'});
        objJDBCTheme.addInfoColumn({column: 'DAY', name:'Day'});
        objJDBCTheme.addInfoColumn({column: 'STATE', name:'State'});
        objJDBCTheme.addInfoColumn({column: 'LOSS', name:'Loss'});
        objJDBCTheme.addInfoColumn({column: 'CROPLOSS', name:'Crop_loss'});
        objJDBCTheme.addInfoColumn({column: 'FATALITIES', name:'Fatalities'});
        objJDBCTheme.addInfoColumn({column: 'INJURIES', name:'Injuries'});
    
        objJDBCTheme.setName('theme_tornado');
        objJDBCTheme.setQuery("SELECT s.geom.sdo_point.x long_loc,s.geom.sdo_point.y lat_loc,year,month,day,state,fatalities,injuries,loss,croploss from tornado_3857 s"+
    (wherec === "" ?"": wherec));
        objJDBCTheme.setRenderingStyleName('V.TORNADO');
    
  3. Create a ServerMapRequest instance and set its properties. For example:

            var req = new OM.server.ServerMapRequest(baseURL);
            req.setProperties({
                dataSource:'storm',
                transparent:true,  // map image is set to be transparent
                antialiase:"false"
            });
            req.addTheme(objJDBCTheme);
    
  4. Create an object containing properties of this dynamic tile layer. For example:

            var dtl_props = {  
                universe: myuniv,            
                tileLayerConfig: myconfig,
                tileServerURL: baseURL + "/omserver",
                enableUTFGrid: true,
                enableUTFGridInfoWindow: true,
                utfGridResolution: 4
            };
    
  5. Create a dynamic tile layer. For example:

      var tornado_damage = new OM.layer.DynamicTileLayer("tornado_damage", dtl_props, req);

The code examples in the preceding steps illustrate the following:

  • The map application fetches map images from a map visualization component server. Therefore, it may use all available features from the map visualization component server.

  • The map image is set to be transparent (that is, the value for property transparent is true). This setting makes all of the non-overlapping features visible when multiple dynamic tile layers are stacked for display. For example, when you overlay a tornado_damage dynamic tile layer on top of a hail_damage dynamic tile layer, you may see both layers on the map when such events (as their names suggest) were happening at non-overlapping locations. This setting is more useful for multiple layers containing linear and point features. Note that since the API allows you to turn on/off a layer's visibility, you can always make a layer of interest stand out and be visible in your application.

  • The dynamic tile layer also enables the map visualization component server's UTFGrid support (specifically, the value for property enableUTFGrid is set to true, with a resolution value set to 4 for the utfGridResolution property). This setting instructs map visualization component's API to request an additional UTFGrid file as a companion of its map tile image. It is a JSON file, and it contains a two-dimensional grid table in UTF encoding, that matches the tile image. It also contains some text attributes for each grid cell.

    When a mouse event (for example, a mouse click) is triggered at an image pixel, its corresponding grid cell can then be located, its UTF code be obtained, and subsequently, the text attributes associated with that grid cell's UTF code can be retrieved and displayed in a popup info window.

    The text attributes contained in that JSON file are specified using the addInfoColumn() method. Those text attributes will be displayed in an info window for a pixel being clicked on the map.

    Note that if server-side predefined geometry themes are used by a dynamic tile layer, the text attributes for an info window must have been specified in theme's <hidden_info> element. This also applies for the base map-based dynamic tile layers, where the predefined themes are found in the map visualization component's base map definition

    A resolution value (for example, "utfGridResolution":4) indicates the width and height of the grid cell compares with its companion map tile image pixel. In this example, one grid cell in the UTFGrid data set represents 16 pixels (4x4=16).

  • This dynamic tile layer makes use of spatial table directly via a ServerJDBCTheme to define its map contents. In its embedded SQL statement, the client web application has the flexibility to construct the whole statement, including the tables to use, the columns to select, and the "where" clause to refine the query. In the code snippets, it assumes that a client function, getWhereClauseFromUI(), only constructs the 'where' clause in the JDBC theme definition.

The dynamic tile layer supported in the Oracle Maps JavaScript API allows the map visualization component server metadata to be used by the tile layer, and it offers flexibility in how a dynamic tile layer is defined and where to fetch its map images by the client application.