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 = 1;
protected $layers = array('world.e00' => 'black');/*, 'river.e00' => 'blue','river.e01' => 'blue','rlroad.e00' => 'red');*/
protected $linesets = array();
protected $message_handle = false;
public function __construct(){
parent::__construct();
$this->set_size_request((310*$this->zoom), (155*$this->zoom));
}
public function send_message($message){
if ($this->message_handle !== false) {
call_user_func($this->message_handle,$message);
}
}
public function set_message_handle($usrfunc){
$this->message_handle = $usrfunc;
}
protected function parse_E00_file($dataFile) {
$lineSet = new LineSet();
$this->send_message("parsing $dataFile");
if ($fp = @fopen(dirname(__FILE__).'/'.$dataFile, 'r')) {
$numRecords = 0;
$ln = 0;
while(0 || $line = fgets($fp, 1024)) {
$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){
$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);
}
public function draw_map(){
foreach ($this->layers as $layer => $color){
if (!isset($this->linesets[$layer])) {
$lineset = $this->parse_E00_file($layer);
$this->linesets[$layer] = $lineset;
}else{
$lineset = $this->linesets[$layer];
}
$this->send_message("converting $layer");
$lines = $this->convert($lineset);
parent::set_color($color);
$this->send_message("drawing $layer");
foreach ($lines as $line) {
$this->draw_line(($line[0]), ($line[1]), ($line[2]), ($line[3]));
while (Gtk::events_pending()) {
Gtk::main_iteration();
}
}
$w = $this->w();
$h = $this->h();
$this->queue_draw_area(0,0, $w, $h);
}
$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 getlocationcoords_inv($x,$y){
$width = 310 * $this->zoom;
$height = 155 * $this->zoom;
$lat = ((($y / $height) * 180) - 90) * -1;
$lon =(($x / $width) * 360) - 180;
return array($lat,$lon);
}
public function zoom_in(){
$this->zoom *=1.2;
$this->set_size_request((310*$this->zoom), (155*$this->zoom));
$this->draw_map();
}
public function zoom_out(){
if ($this->zoom !== 1) {
$this->zoom *=0.8;
}
$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 mouse_move(){
list($x, $y) = $this->map->get_pointer();
list($lat, $lon) = $this->map->getlocationcoords_inv($x,$y);
$this->set_message("lat : $lat / lon : $lon");
}
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_events(MOUSE_EVENTS);
$this->map->connect_simple('motion-notify-event',array($this,'mouse_move'));
$this->map->set_message_handle(array($this,'set_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 set_message($message){
$this->statusbar->pop(0);
$this->statusbar->push(0,$message);
//echo "$message\n";
}
}
define("MOUSE_EVENTS", Gdk::POINTER_MOTION_MASK
| Gdk::BUTTON_PRESS_MASK
| Gdk::BUTTON_RELEASE_MASK
| Gdk::POINTER_MOTION_HINT_MASK);
$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();
?>