Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why does the renderer have to use BitmapSource ? #24

Open
ststeiger opened this issue Aug 27, 2021 · 0 comments
Open

Why does the renderer have to use BitmapSource ? #24

ststeiger opened this issue Aug 27, 2021 · 0 comments

Comments

@ststeiger
Copy link

ststeiger commented Aug 27, 2021

Your render method, aka. Task<BitmapSource> Render(... adds a dependency on Windows.
That's an aweful shame.
Now I get it, you want to use it in WPF.

But you could just as well use Skia everywhere in the renderer, and instead return a byte-array.
Then you can create an extension method in WPF, that takes the byte-array and converts it into a BitmapSource.
I've done that over here, and the result should run on Linux, too, provided Skia native dependencies are installed there.
Plus I've added a Live-Raster-Tile-Server, created from the WPF-independent VectorTileRenderer.
But I guess your whole point is that using your way, you don't have to do that conversion.
Maybe you should instead take a skia-bitmap/canvas that writes to image-source as input parameter in an overload,
then put the rest into an extension method in the WPF project.
On the other hand, if you do that, you get a dependency on Skia in client-code, so you can't change the renderring method anymore.
Maybe better just return a byte-array.
That adds a dependency to nothing.
Or create a WPF extension dll, where you wrap the skia calll in and return the BitmapSource.
That way you can add the skia canvas overload as internal, and make internals visisble to the wpf-extension dll only.

One more thing:
It should take an input-language as parameter.
For example, in MapBox-GL, I load the respective labels like here (tested with russian characters)
Coalesce("name:ru", "name:latin", "name:nonlatin")
where "ru" would be parametrized as user-provided primary-language.

      gl._glMap.on('load', function ()
       {
           var keys = Object.keys(gl._glMap.style._layers);

           for (var i = 0; i < keys.length; ++i)
           {
               if (((gl._glMap.style._layers[keys[i]].layout || {})._values || {})["text-field"])
               {
                   if (gl._glMap.style._layers[keys[i]].layout._values["text-field"].value.value.indexOf("name:") != -1)
                   {
                       // var languageField = "name:" + getUserLanguage();
                       // gl._glMap.setLayoutProperty(keys[i], 'text-field', ["coalesce", ["get", languageField], ["get", "name:latin"], ["get", "name:nonlatin"]]);
                       gl._glMap.setLayoutProperty(keys[i], 'text-field', ["coalesce", ["get", "name:ru"], ["get", "name:latin"], ["get", "name:nonlatin"]]);
                   }

               }

           } // Next i

       });

Also, you can get rid of the dynamic in Style.cs, that way you don't need to add the whole system-dynamic runtime in NetStandard:

dynamic jObject = JObject.Parse(json);
foreach (JProperty jSource in jObject.sources)
foreach (var jLayer in jObject.layers)

becomes

JProperty srcs = jObject.Property("sources");
if (srcs != null && srcs.Type == JTokenType.Property && srcs.Value.Type == JTokenType.Object)
{
    foreach (JProperty jSource in ((JObject)srcs.Value).Properties()) {

and

JProperty layers = jObject.Property("layers");

if (layers != null && layers.Value != null && layers.Value.Type == JTokenType.Array)
{
    foreach (JObject jLayer in layers.Value)

Otherwise, I'd say it's pretty good work for 4 days of effort !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant