No announcement yet.

How to implement a public non WMS tile set ?

  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    The developer discovered that reducing the tileWidth and tileHeight values from 256 to 128 improved the quality of tiles rendered to the scene:

    Click image for larger version

Name:	nwww-improved-quality.png
Views:	1
Size:	923.3 KB
ID:	158533

    Is that to be expected ?

    It would be nice to see an explanation of all the variable parameters available to us for the purpose of setting render quality.


    • #17
      Good! But again the layer is not the best to test render quality. It is all a matter of compromise, between zoom level, labels readability, tile size, number of tiles, speed, your network... For the java version, it was the crucial debate, and AFAIK there is no caching for the web version, so every tile has to go through the wire, at all times. You may search the forum with the "needToSplit" function, if the web version is close to the java one, there must be a similar function you may tweek as you like. Cheers!


      • #18
        Hi frenchy

        True it would be better to test with a more detailed and predictable tileset.

        That's interesting when you say no caching for web version, do you mean no caching in the client browser ?

        Thank you for pointing out needToSplit I think that will be very useful to play with. I liked this explanation:


        • #19
          Hi timoto,
          You may try with mapbox, along with a valid key in the URL... But again copyrights...
          Don't know much the web version, but I imagine caching in the browser is just good for saving preferences stuff, not thousands of "memory files"... ?
          For needSplit, I remember a guy named "vash" from Thales I think, who had a version that worked quite well. Search the forum.


          • #20
            Hi frenchy

            Actually this prototype now displays 2 layers, Stamen watercolor rastered tiles and Mapbox hillshading vector tiles. The hillshading is more noticeable when you zoom in.

            Most web browsers cache lots more than preferences. They store the html pages you visit and the content files such as images, video etc on your computer.


            • #21
              Yes, but with a limited size and duration in time. The cache of WWJ was infinite (I have nearly 1To on disk!), and WWJ had no response time for tiles on disk, with a web app, you finally wait a lot to have tiles visible. I think there are cache requests in the Github, don't know if they are resolved. There should be a mechanism to store frequently visible (high altitude) tiles, and frequently visited places, which doesn't seem to be in place, even with Google Maps...
              Seen the hillshades, good, you should now try a site with labels...


              • #22
                There is certainly something odd going on with cache.

                Whilst at times it may appear that there is no cache this simply can't be true. I had a situation where I had modified my map tiles in mapbox to include labels, then viewed those labels in a basic webpage to verify the update was being rendered. But when returning to my NWWW scene, after clearing the browser cache, some tiles in the scene were including the labels where expected, and other tiles were rendering without labels. This means that there must be a cache with NWWW servers, which I'm sorry to say is not behaving as expected.

                In the end I had to create an entirely new mapbox style with a new URL to force the scene to render a fresh tileset and not whatever had been stored on NWWW servers.

                So whilst some tiles can be persistent as demonstrated, lots of tiles are not.

                Tiles Lag

                This video shows how moving the globe around somewhat erratically, will shake up NWWW so much that it takes ages to catch up with the current static screen.

                Cache Dies

                This video shows even after a short time tiles previously loaded are then re-loaded.
                Last edited by timoto; 07-31-2018, 08:02 AM.


                • #23
                  Strange behaviours indeed. I dont have any of these with my java version displaying the same layers. Would it be because javascript cant handle multiple threads afaik ? In the first video you probably zoom in-out too much, web mapping doesnt like that.. in the second one, the white tiles are a problem i had years ago with the java but without being stuck.
                  it would be good to have an input from official guys to clarify things..


                  • #24
                    Yes, official guys where are you ?

                    Yes, people who use the web are quite erratic and do things like zoom in and out quickly because they are easily distracted and don't have time to waste.

                    Ideally there should be some code to deal with this eg

                    IF zoom, rotation or position changes THEN stop loading the previous tiles in viewport AND load the new tiles in viewport.

                    Obviously that is an over simplification, and perhaps that is not the cause of the issue, but it does seem that the engine gets overloaded with requests and spends a lot of time running through old requests that are no longer of interest.

                    By the way Chrome browser cache IS storing files with each zoom, rotation, position change. If you monitor the cache folder whilst zooming in and out you can see the files being created, eventually when all the tiles have loaded for your zoom, the tiles are rendered without delay (but not always), because they are in the cache. Local cache does appear to work.

                    Here are some videos:

                    Browser cache updates

                    Cache unchanged but with tile render delay

                    Fast zooming without blank spots

                    Tilting during zoom in always causes blank spots

                    It seems to me that even if the tiles are in the cache the engine sometimes has trouble calculating which tiles to render leading to long delays in rendering the scene. Is there a way to resolve this issue ?
                    Last edited by timoto; 08-01-2018, 11:13 AM.


                    • #25
                      We used a separate javascript file with the following text in it, then we reference that js file, then we call StamenWaterColorLayer.Create():

                      * This class shows mercator tiles in a layer. (Stamen Water Color)

                      var StamenWaterColorLayer = function() //Defines the name of this class
                      //class variables
                      var layer = null; //The layer that is returned by the Create function
                      var levelZeroOffset = 0; //The number of levels deep before the first tiles are used from this tile set. For instance. 0 means a single image for level zero. 1 means there are 4 images for level 0, 2 means there are 16 images for level 0, etc. (as tiles are subdivided in half in width and height (quaded) each zoom level)

                      //This is a public function that is called by default.js. This function builds the entire layer and returns it to default.js.
                      var Create = function() //Defines a Create function within our TerminalServiceVolumesCore30 function. Currently Create is the only function within the TerminalServiceVolumesCore30 function that is exposed publically.

                      var displayName = "Stamen Water Color";
                      var imageFormat = "image/png";
                      var numLevels = 8;

                      //If we were using full sphere we would do the following:
                      //var sector = WorldWind.Sector.FULL_SPHERE;
                      //var levelZeroDelta = new WorldWind.Location(180, 360);

                      //But to avoid the "getting a ton of tiles at the poles" issue, we do the folllowing.
                      var sector = new WorldWind.Sector(-85.05, 85.05, -180, 180); //Sets the upper and lower bound to 85.05 instead of full sphere.
                      var levelZeroDelta = new WorldWind.Location(85.05, 180); //Since we aren't using full sphere, our level zero delta is adjusted accordingly.

                      layer = new WorldWind.MercatorTiledImageLayer(sector , levelZeroDelta, numLevels, imageFormat, displayName, 256, 256);

                      layer.imageSize = 256;
                      layer.detailControl = .8; // default is 1.75
                      layer.displayName = displayName;
                      layer.enabled = true;
                      layer.detectBlankImages = false;

                      layer.mapSizeForLevel = MapSizeForLevel;

                      layer.urlBuilder = {};
                      layer.urlBuilder.urlForTile = UrlForTile;

                      layer.doRender = function(dc) {dc.fadeTime=0; WorldWind.MercatorTiledImageLayer.protot, dc);};

                      layer.createTopLevelTiles = CreateTopLevelTiles;
                      return layer;

                      }; //End of the Create function

                      * This function calculates the total number of pixels across of all the images combined for a given zoom level
                      var MapSizeForLevel = function(levelNumber)
                      return 256 * Math.pow(2,(levelNumber + levelZeroOffset)); //The total number of pixels across of all the images combined for this zoom level. For instance for 256 pixel images, level 0, and a zero level offset would be 256, i.e. one 256 pixel image across. Whereas level 1 and a 0 level offset would be 512 pixels across. (i.e. two 256 images wide and two 256 pixel images tall), etc. (And, you can see how the offset would jump you up a zoom level factor, as for 256 pixel images, level 0, and a level 1 offset would be 512 pixels across for zoom level 0)

                      * This function was neccessary in order to set the level zero tiles.
                      * (And, as such, this fixes the odd intermittant issue where World Wind would sometimes not be able to obtain ground altitudes)
                      var CreateTopLevelTiles = function (dc)
                      this.topLevelTiles = [];

                      //Here we loop through rows and colums based on the levelZeroOffset in order to push the topLevelsTiles (which is neccessary to correct the intermittant ground altitude bug)
                      for (var row = 0; row <= levelZeroOffset; row++) //Loop
                      for (var col = 0; col <= levelZeroOffset; col++) //Loop
                      this.topLevelTiles.push(this.createTile( null, this.levels.firstLevel(), row, col)); //Note a level 0 tileset will have just one tile (0,0). If it were an offset of 1 then we would set 4 tiles here. 0,0, 0,1, 1,0, and 1,1, and if an offset of 2 then 16 tiles.


                      var UrlForTile = function(tile, imageFormat)
                      //Example call we are looking for:
                      //Where the first 0 is the zoom level
                      //The second 0 is the column
                      //And the third 0 is the row.
                      //The tile numbering scheme in this tile set are numbered top to bottom, left to right.

                      var x = tile.column;
                      var y = tile.row;
                      var z = tile.level.levelNumber;

                      var url = "" + z + "/" + x + "/" + y + ".jpg";

                      //Eventually to use the AOI/SBS Monitor tileset redirector we will be able to use a call like this which will route all tile calls through our server.
                      //var url = "tile.ashx?proxyurl=" + z + "/" + x + "/" + y + ".jpg";

                      //The tile numbering scheme in this tile set are numbered top to bottom, left to right.
                      //However, some mercator tileset are numbered bottom to top, left to right.
                      //Therefore for those types of tile sets you would have to reverse the order of the rows as follows.

                      //To reverse the order of our rows we have to subtract the largest possible row value from the row returned, this will reverse the order of our rows for us.

                      //var levelPlusFactor = tile.level.levelNumber + 3; //Here we determine our zoom level. Note: We are zooming 3 levels deep for our zero zoom in this tile, but yours may not need that.
                      //var reverseRowNumberMax = (Math.floor(Math.pow(levelPlusFactor,2,) )) - 1; // Now we figure out the max possible rows for that zoom level. We do this by raising 2 to the power of our zoom level, then subtract 1 since a zero row is also used. (Note we raise 2 to the power of the zoom level because each zoom level has tiles that are half the width, and half the height of the zoom level higher.)
                      //var rowReversed = reverseRowNumberMax - tile.row; //Now that we know our max possible rows, we subrtract that from the what would otherwise be the actual row for a standard mercator tile set that didn't need to be reversed. That in turn yields the correct row number because that reverses the order of the rows. For instance if the row was 2 and the maxrows was 15 then 15-2 = 13 thus taking what was 2 (two up from the bottom) and making it 13 (two down from the top)

                      //To figure out how you would get the values for the levelZeroDelta see the following remmed out lines.

                      //Here we set the levelZeroDelta based on how many zoom levels deep to start for zoom level 0 which in our case for this tile set which was 3.
                      //var levelZeroDelta = new WorldWind.Location(180, 360); //Tells the tile layer how far over in lon and how far down in lat that starts where our first tile begins. i.e. our x and y values start at this lat lon. (we do this for tile sets that were not turned into images from lat zero and lon zero.) i.e. for tiles sets where lat zero and lon zero do not define the top left edge of the tile set (as if it were a single image.) (in other words we need to know the lat and lon of where to start counting our x and y offsets from)(and that is totally dependent on how the tile set was created) This particular tile set starts at 22.5 degrees lat, 45 degrees lon. so that where we'll put our o,o,o tile. (as opposed to lat zero lon zero)

                      //We calculate the angle values based on a zoom of 3 the following way.

                      //tile.getLevelNumber() + 3 where the + 3 relates to how many zoom levels deep to start for zoom level 0.
                      //This "zoom levels deep value to start to start for zoom level 0" is directly related to the levelZeroDelta values.
                      //For tile.level.levelNumber + 0 its lat 180 lon 360
                      //For tile.level.levelNumber + 1 its lat 90 lon 180
                      //for tile.level.levelNumber + 2 its lat 45 lon 90
                      //For tile.level.levelNumber + 3 its lat 22.5 lon 45 //Thus we would use 22.5 and 45 for our levelZeroDelta for a zoom level 3 tile set since we would zoom 3 levels deep for zoom level 0.
                      //For tile.level.levelNumber + 4 its lat 11.25 lon 22.5 //We would have used these values had we started 4 levels deep.
                      //In other words for every zoom level higher where your starting zoom level is, half your lat and lon levelZeroDelta values.

                      return url;

                      var pub = {};
                      pub.Create = Create;
                      StamenWaterColorLayer = pub;

                      StamenWaterColorLayer(); //Calls the function above. (to create a singleton instantiation)