rendered paste body<?php
class LineSet {
var $lines = array();
var $min = false;
var $max = false;
function Image_GIS_LineSet($color = 'black') {
$this->color = $color;
}
function addLine($x1, $y1, $x2, $y2) {
$this->lines[] = array($x1, $y1, $x2, $y2);
if ($this->min == false) {
$this->min['x'] = min($x1, $x2);
$this->min['y'] = min($y1, $y2);
$this->max['x'] = max($x1, $x2);
$this->max['y'] = max($y1, $y2);
} else {
$this->min['x'] = min($this->min['x'], $x1, $x2);
$this->min['y'] = min($this->min['y'], $y1, $y2);
$this->max['x'] = max($this->max['x'], $x1, $x2);
$this->max['y'] = max($this->max['y'], $y1, $y2);
}
}
}
class Map_Core extends GtkDrawingArea {
# prefix class attributes with "_" to avoid collisions
# with GtkDrawingArea attributes.
protected $_pixmap;
protected $_gc;
protected $_realized;
function __construct() {
parent::__construct();
$this->connect('expose_event',
array($this, 'expose_event'));
$this->connect('configure_event',
array($this, 'configure_event'));
$this->connect('realize',
array($this, 'realize'));
$this->set_events(Gdk::EXPOSURE_MASK
| Gdk::LEAVE_NOTIFY_MASK);
$this->_pixmap = null;
$this->_gc = null;
$this->_realized = false;
}
function realize() {
$this->_realized = true;
}
function realized() {
return $this->_realized;
}
function configure_event($widget, $event) {
$w = $this->width();
$h = $this->height();
# allocate a new pixmap of the requested size ($this->allocation)
$this->_pixmap = new GdkPixmap($this->window, $w, $h, -1);
# clear pixmap (white color)
$this->_pixmap->draw_rectangle($this->style->white_gc, true,
0, 0, $w, $h);
return true;
}
function expose_event($widget, $event) {
$this->window->draw_drawable($this->style->fg_gc[$this->state],
$this->pixmap(),
$event->area->x, $event->area->y,
$event->area->x, $event->area->y,
$event->area->width, $event->area->height
);
return false;
}
function set_color($color) {
$col = $this->colormap()->alloc_color($color);
if ($col === false)
return $this->foreground('black');
return $this->gc()->set_foreground($col);
}
function colormap() {
return $this->gc()->get_colormap();
}
function pixmap() {
if (!$this->realized()) {
trigger_error("Widget not realized ; can't get pixmap");
return null;
}
return $this->_pixmap;
}
function gc() {
if (!$this->realized()) {
trigger_error("Widget not realized ; can't get GC");
return null;
}
if ($this->_gc == null)
$this->_gc = new GdkGc($this->pixmap());
return $this->_gc;
}
function width() {
return $this->allocation->width;
}
function height() {
return $this->allocation->height;
}
function w() {
return $this->width();
}
function h() {
return $this->height();
}
}
class Map extends Map_Core{
protected $zoom = 5;
protected $message_handler;
protected $layers = array('world.e00');
public function __construct(){
parent::__construct();
$this->set_size_request((310*$this->zoom), (155*$this->zoom));
}
public function set_message_handler($usrfunction){
$this->message_handler = $usrfunction;
}
public function send_message($message){
call_user_func($this->message_handler,$message);
}
protected function parse_E00_file($dataFile) {
$lineSet = new LineSet();
if ($fp = @fopen(dirname(__FILE__).'/'.$dataFile, 'r')) {
$numRecords = 0;
$ln = 0;
while(0 || $line = fgets($fp, 1024)) {
$ln ++;
$this->send_message("Parse $dataFile E00 line - $ln");
while (Gtk::events_pending()) {
Gtk::main_iteration();
}
//echo "line : $ln\n";
if ($numRecords == 0 &&
preg_match("#^\s+([0-9]+)\s+([-0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)#", $line, $a)) {
$numRecords = $a[7];
$pl['x'] = -1;
$pl['y'] = -1;
}
else if ($numRecords &&
preg_match("#^([ -][0-9]\.[0-9]{7}E[-+][0-9]{2})([ -][0-9]\.[0-9]{7}E[-+][0-9]{2})([ -][0-9]\.[0-9]{7}E[-+][0-9]{2})([ -][0-9]\.[0-9]{7}E[-+][0-9]{2})#", $line, $a)) {
if ($pl['x'] != -1 &&
$pl['y'] != -1) {
$lineSet->addLine($pl['x'], $pl['y'], $a[1], $a[2]);
}
$numRecords--;
$lineSet->addLine($a[1], $a[2], $a[3], $a[4]);
$pl['x'] = $a[3];
$pl['y'] = $a[4];
$numRecords--;
}
else if ($numRecords &&
preg_match("#^([ -][0-9]\.[0-9]{7}E[-+][0-9]{2})([ -][0-9]\.[0-9]{7}E[-+][0-9]{2})#", $line, $a)) {
if ($pl['x'] != -1 &&
$pl['y'] != -1) {
$lineSet->addLine($pl['x'], $pl['y'], $a[1], $a[2]);
$pl['x'] = $a[1];
$pl['y'] = $a[2];
}
$numRecords--;
}
}
@fclose($fp);
return $lineSet;
}
return false;
}
public function convert($lineset) {
$latlon = $lineset->lines;
$i = 0;
foreach ($latlon as $line){
$this->send_message("converting lat/lon to x,y - ".(round($i/(count($latlon)/100),0))."%");
$x_y1 = $this->getlocationcoords($line[0],$line[1],(310*$this->zoom),(155*$this->zoom));
$lines[$i][0] = $x_y1['x'];
$lines[$i][1] = $x_y1['y'];
$x_y2 = $this->getlocationcoords($line[2],$line[3],(310*$this->zoom),(155*$this->zoom));
$lines[$i][2] = $x_y2['x'];
$lines[$i][3] = $x_y2['y'];
while (Gtk::events_pending()) {
Gtk::main_iteration();
}
$i++;
}
return $lines;
}
public function draw_line($x1, $y1, $x2, $y2){
$this->pixmap()->draw_line($this->gc(), $x1, $y1, $x2, $y2);
$w = $this->w();
$h = $this->h();
$this->queue_draw_area(0,0, $w, $h);
}
public function draw_map(){
parent::set_color('black');
foreach ($this->layers as $layer){
$lineset = $this->parse_E00_file($layer);
$lines = $this->convert($lineset);
$i = 1;
foreach ($lines as $line) {
$this->send_message("Drawing $layer - ".(round($i/(count($lines)/100),0))."%");
$this->draw_line(($line[0]), ($line[1]), ($line[2]), ($line[3]));
while (Gtk::events_pending()) {
Gtk::main_iteration();
}
$i++;
}
}
$this->send_message('');
}
protected function getlocationcoords($lon, $lat, $width, $height) {
$x = (($lon + 180) * ($width / 360));
$y = ((($lat * -1) + 90) * ($height / 180));
return array("x"=>round($x),"y"=>round($y));
}
public function zoom_in(){
$this->zoom++;
$this->set_size_request((310*$this->zoom), (155*$this->zoom));
$this->draw_map();
}
public function zoom_out(){
if ($this->zoom != 1) {
$this->zoom--;
}
$this->set_size_request((310*$this->zoom), (155*$this->zoom));
$this->draw_map();
}
}
class Gtk2_Map extends GtkVBox {
protected $toolbar;
protected $zoom_in;
protected $zoom_out;
protected $scroll;
protected $fixed;
protected $map;
protected $statusbar;
public function __construct(){
parent::__construct();
$this->toolbar = new GtkToolBar();
$this->zoom_in = new GtkToolButton();
$this->zoom_in->set_stock_id(Gtk::STOCK_ZOOM_IN);
$this->zoom_in->connect_simple('clicked',array($this,'zoom_in'));
$this->zoom_out = new GtkToolButton();
$this->zoom_out->set_stock_id(Gtk::STOCK_ZOOM_OUT);
$this->zoom_out->connect_simple('clicked',array($this,'zoom_out'));
$this->toolbar->add($this->zoom_in);
$this->toolbar->add($this->zoom_out);
$this->scroll = new GtkScrolledWindow();
$this->fixed = new GtkFixed();
$this->statusbar = new GtkStatusBar();
$this->statusbar->set_has_resize_grip(false);
$this->map = new Map();
$this->map->set_message_handler(array($this,'message'));
$this->fixed->put($this->map,0,0);
$this->scroll->add_with_viewport($this->fixed);
$this->pack_start($this->toolbar,false,false);
$this->pack_start($this->scroll);
$this->pack_end($this->statusbar,false,false);
Gtk::timeout_add(1, array($this, 'zoom_out')); // note 2
}
public function zoom_in(){
$this->zoom_in->set_sensitive(false);
$this->zoom_out->set_sensitive(false);
$this->map->zoom_in();
$this->zoom_in->set_sensitive(true);
$this->zoom_out->set_sensitive(true);
}
public function zoom_out(){
$this->zoom_in->set_sensitive(false);
$this->zoom_out->set_sensitive(false);
$this->map->zoom_out();
$this->zoom_in->set_sensitive(true);
$this->zoom_out->set_sensitive(true);
}
public function message($message){
$this->statusbar->pop(0);
$this->statusbar->push(0,$message);
//echo $message."\n";
}
}
$window = new GtkWindow();
$window->connect_simple('destroy', array('gtk', 'main_quit'));
$window->set_title('GIS Maping demo');
$window->set_position(Gtk::WIN_POS_CENTER);
$map = new Gtk2_Map();
$window->add($map);
$window->set_size_request((400), (200));
$window->show_all();
Gtk::main();
?>