howardjones / network-weathermap

Network Weathermap draws diagrams from data
http://www.network-weathermap.com/
MIT License
425 stars 94 forks source link

Rewriting graphics functions to support other rendering engines #23

Open misiek08 opened 9 years ago

misiek08 commented 9 years ago

Hello! I'm using weathermap for few maps that are over 5k x 5k pixels in size and in my opinion it's time to rewrite code to use another rendering engine to make it look more fresh. I wonna replace all function calls with something like RE[::|->]filledarc(...) (RE for Render Engine).

Is now good time to fork project and replace that code or it's better for me to write those render engine class and write script to rewrite [by regex] all calls to graphics functions (to make it possible replacing calls in future versions of map)?

howardjones commented 9 years ago

I'm halfway through a pretty major refactoring job, to pull a lot of code out of the WeatherMap class that shouldn't really be there. This includes new dedicated classes for link and scale drawing, too.

Agreed about the issues with gd. What did you have in mind as a replacement?

misiek08 commented 9 years ago

I'm going to write script, which will replace all gd function with static calls to some class and there I wonna call ImageMagick functions. IM library is a lot better at rendering everything - it generates smooth images with great antialiasing (and it's a little bit faster, but that's not my point).

howardjones commented 9 years ago

OK - up to not that long ago, Weathermap actually had a wrapper around all the GD functions already, from when I experimented with Cairo and SVG... it wouldn't be that hard to put that back in. So then there would be a WMGraphics class and subclasses for GD, IM, Cairo etc. Font handling is probably going to be the tricky part - everything does that differently, and a few parts of weathermap expect to be able to get a bounding box for a string of text. It should be done so that nothing outside the rendering class needs to know about the specifics though - so probably not static calls, but some singleton object with the state of the graphics system.

misiek08 commented 9 years ago

It's exactly what I'm thinking about, the class can be singleton and contain data for image to know what and with what to do. My first version makes an static array with images and allow same calls as with GD, where first argument it's just unique integer in that static array simulating separate image resource. Bringing back wrapper is needed in my opinion. Each subclass or implementation will get same data for fonts and will have to use it's internal functions to get similiar result as with GD. 9 kwi 2015 11:27 "Howard Jones" notifications@github.com napisał(a):

OK - up to not that long ago, Weathermap actually had a wrapper around all the GD functions already, from when I experimented with Cairo and SVG... it wouldn't be that hard to put that back in. So then there would be a WMGraphics class and subclasses for GD, IM, Cairo etc. Font handling is probably going to be the tricky part - everything does that differently, and a few parts of weathermap expect to be able to get a bounding box for a string of text. It should be done so that nothing outside the rendering class needs to know about the specifics though - so probably not static calls, but some singleton object with the state of the graphics system.

— Reply to this email directly or view it on GitHub https://github.com/howardjones/network-weathermap/issues/23#issuecomment-91172807 .

misiek08 commented 9 years ago

Firstly I'm going to create such thing:

class GraphicsEngine {
    public function __call($name, $args)
    {
        return call_user_func_array($name, $args);
    }
}

$ge = new GraphicsEngine;
$im = $ge->imagecreate(150, 250);

Then I will be able to set anything in $ge and handle it my way. Are you ok with that or should I write full class and do something like:

<?php

interface Renderer {
    public function createimage($w, $h);
}

class ImagickRenderer implements Renderer {
    private $images = array();

    public function createimage($w, $h)
    {
        $rid = uniqid();
        $this->images[$rid] = new Imagick($w, $h, ImagePixel('white'));
        return $rid;
    }
}

?

howardjones commented 9 years ago

Actually, I think it should be a full class. Here's why:

1) I'm in the process of moving all the geometry stuff to use WMPoint, WMRectangle and WMVector classes instead of lots of loose x,y pairs. The GraphicsEngine class should take those, and translate as necessary for the actual backend. 2) Same thing with WMColour 3) Same thing with WMFont

Basically, I'm already working on hiding the detail of GD where I can, and reducing the amount of repeated stuff in the main classes. So for example imagerectangle should become something like $ge->drawRectangle($rectangleObject, $colourObject), and it can deal with those internally in a way that's appropriate for GD, SVG, ImageMagick or whatever.

On 20/04/2015 18:57, Misiek wrote:

Firstly I'm going to create such thing:

class GraphicsEngine { public function __call($name,$args) { return call_user_func_array($name,$args); } }

$ge = new GraphicsEngine; $im = $ge->imagecreate(150,250);

Then I will be able to set anything in $ge and handle it my way. Are you ok with that or should I write full class and do something like:

<?php

interface Renderer { public function createimage($w,$h); }

class ImagickRenderer implements Renderer { private $images = array();

 public  function  createimage($w,$h)
 {
     $rid  =  uniqid();
     $this->images[$rid]=  new  Imagick($w,$h, ImagePixel('white'));
     return  $rid;
 }

}

?

— Reply to this email directly or view it on GitHub https://github.com/howardjones/network-weathermap/issues/23#issuecomment-94524547.

misiek08 commented 9 years ago

If it's possible - let me know in this issue when code will be in good condition for extending to other rendering engines, so I can work on ImageMagick version.

Now I'm looking for someone with big map, who can give me access to data provided for map, so I can test my code. Maybe someone here is watching this repo and can help me?

howardjones commented 9 years ago

OK - I'm still working through the very large methods in Node and Link.

I have a small collection of user maps - I've been meaning to do some search/replace to make them anonymous so they can be added to the repo as test inputs - I'll get those done (and of course if there are others that could be donated). I have been working on performance with a couple of users and have some test maps from them.

There's already a fairly complete set of tests for Weathermap output though - they work by pixel comparison, so they will fail with another rendering engine, but they do test most features. Check out the configs in test-suite/tests (and the expected outputs in test-suite/refererence). Your engine should be able to render all 160+ of those and get similar results.

I guess we'll have to update the testing code to test multiple graphics engines too. reference-gd, reference-imagemagick etc.

misiek08 commented 8 years ago

What do you think about using Imagine (repo)?