Git Product home page Git Product logo

Comments (7)

manthey avatar manthey commented on June 14, 2024 1

In any tileLayer (including the osmLayer), you can set the url to a function rather than a string. This is a function that gets passed (x, y, z, subdomains) and returns a value that can be set as the src of an HTML Image object. Although this is usually a url, it could be, for instance, a data:image/png;base64,... string or anything else Image.src accepts.

from geojs.

manthey avatar manthey commented on June 14, 2024 1

I think you'd have to override some of the methods in the tileLayer to accomplish this. For instance, suppose you create an intial layer with a url of something neutral (a static string of a white png, for instance). Then, once the layer is created, you could do something like layer._getTile = newGetTileFunction, where newGetTileFunction would mimic what is in tileLayer's _getTile, but return a new subclassed version of imageTile. Your subclassed version of imageTile would inherit from imageTile and replace the fetch method where instead of the line which reads this._image.src = this._url, you would call your async function which, on success or failure would set that src with your new value.

from geojs.

zhusihan-python avatar zhusihan-python commented on June 14, 2024

In any tileLayer (including the osmLayer), you can set the url to a function rather than a string. This is a function that gets passed (x, y, z, subdomains) and returns a value that can be set as the src of an HTML Image object. Although this is usually a url, it could be, for instance, a data:image/png;base64,... string or anything else Image.src accepts.

hello, sir, i tried to use function instead of a string, it worked yet confront another problem that the image data is fetched asynchronous, as the communication in qwebchannel.js is asynchronous, then how to correctly return the value in the function?

when i call Bridge.get_tile() of PyQt api, we can see the image data is returned success below, but the function return before Bridge finish get image from get_tile, so the tileUrl return in function is undefined
the sync version didn't work

var tile_data = undefined;
tileUrl = function (x, y, z, subdomains) {
  console.log("input x,y,z,subdomains in index.html", x, y, z, subdomains);

  Bridge.get_tile(x, y, z, function (pyval) {
    tile_data = "data:image/png;base64," + pyval;
    console.log("tile_data return by get_tile", tile_data);
  });

  console.log("tile_data before return in tileUrl", tile_data);
  return tile_data;
}

image

then i tried the async version

tileUrl = async function (x, y, z, subdomains) {
      console.log("input x,y,z,subdomains in index.html", x, y, z, subdomains);

      let promise = new Promise(function (resolve, reject) {
        Bridge.get_tile(x, y, z, function (pyval) {
          tile_data = "data:image/png;base64," + pyval;
          // console.log("tile_data in index.html", tile_data);
          resolve(tile_data);
        });
      });

      let res = await promise;
      console.log("res return by promise", res);
      return res;
    };

now the function return after the promise return the res, the final res data return in function is ok i think, yet the image data is not shown either
image
is there somethin i did wrong, or the tileUrl does not support the async function?

from geojs.

zhusihan-python avatar zhusihan-python commented on June 14, 2024

i test the async function in web service, it turns out url function didn't support async
and i found that my code in createLayer get a error:

createLayer get err TypeError: Cannot read property 'indexOf' of undefined
    at e.fetch (geo.min.js:1)
    at geo.min.js:1
    at l (geo.min.js:64)
    at Object.fireWith [as resolveWith] (geo.min.js:64)
    at Object.Deferred.S.each.o.<computed> [as resolve] (geo.min.js:64)
    at e.next_item (geo.min.js:1)
    at e.add (geo.min.js:1)
    at e.then (geo.min.js:35)
    at geo.min.js:35
    at Array.forEach (<anonymous>)

here is the related code

const params = geo.util.pixelCoordinateParams(
  '#imageViewer', tileinfo.sizeX, tileinfo.sizeY, tileinfo.tileWidth, tileinfo.tileHeight);
params.layer.url = tileUrl;
console.log("get_metadata else params layer", params.layer);
viewer = geo.map(params.map);

viewer.zoomRange({
  // do not set a min limit so that bounds clamping determines min
  min: -Infinity,
  max: 12,
});
console.log("get_metadata else viewer", viewer);
try {
  imageLayer = viewer.createLayer('osm', params.layer);
}
catch (err) {
  console.log("createLayer get err", err)
}

console.log("imageLayer in get_metadata else", imageLayer);

the viewer and params layer value are like below
image

is there any idea how to fix it

from geojs.

zhusihan-python avatar zhusihan-python commented on June 14, 2024

if the tileUrl is undefined, createLayer will raise an error
is there a way to make url accept function return a promise but not return a image instance immediately?

from geojs.

zhusihan-python avatar zhusihan-python commented on June 14, 2024

I think you'd have to override some of the methods in the tileLayer to accomplish this. For instance, suppose you create an intial layer with a url of something neutral (a static string of a white png, for instance). Then, once the layer is created, you could do something like layer._getTile = newGetTileFunction, where newGetTileFunction would mimic what is in tileLayer's _getTile, but return a new subclassed version of imageTile. Your subclassed version of imageTile would inherit from imageTile and replace the fetch method where instead of the line which reads this._image.src = this._url, you would call your async function which, on success or failure would set that src with your new value.

hello @manthey , i reimplement a griderImageTile which inherit from imageTile and get tile by my api in _getTile , and implement griderLayer which inherit from tileLayer, after fixing some errors, this is my code

now i get the image data as expected, the datas are
almost the same as the web server version before this line in webgl_tileLayer,
image

yet my canvas didn't draw anything, what happend in webgl_tileLayeris draw, are there some draw signals or events i was missing?
image

here is the variables comparsion between web tile server and pyqt tile server:
image

from geojs.

zhusihan-python avatar zhusihan-python commented on June 14, 2024

sor its my fault that the wrapper div is not setting appropriately that the canvas didn't show, not related to the drawing events
here is the code that works if anyone are interested
image
thanks for all the help and guidance @manthey

from geojs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.